Re: [PATCH v2 1/3] drm/msm/mdss: convert UBWC setup to use match data
On 24/01/2023 03:48, Abhinav Kumar wrote: On 1/19/2023 9:26 PM, Dmitry Baryshkov wrote: On Fri, 20 Jan 2023 at 00:54, Abhinav Kumar wrote: On 1/17/2023 5:04 PM, Dmitry Baryshkov wrote: To simplify adding new platforms and to make settings more obvious, rewrite the UBWC setup to use the data structure to pass platform config rather than just calling the functions direcly. Signed-off-by: Dmitry Baryshkov I was reviewing this series and https://patchwork.freedesktop.org/series/111732/ together. More I think about it, it seems like we are duplicating the same values here and in the catalog. Yes, these two are different drivers. But now that you are adding the UBWC entries here using the compatible string so you are creating something like a "catalog" here. In that case, why dont we remove the entries from dpu catalog and in the DPU driver get the parent's match data as we know that the msm_mdss is the parent of DPU driver I should give it a thought, especially since we are trying to clean up the DPU catalog. I just went through the cover letter of https://patchwork.freedesktop.org/patch/519752/ and it mentions "My itent is to land both series and then to make DPU request this data from the MDSS driver" This means that the parent data suggestion will be implemented? Yes, at some point. You probably saw the dpu_ubwc_cfg structure. As I wrote, I'd like to get it from MDSS. Just looking for a best way to do this. -- With best wishes Dmitry
Re: [PATCH v2 1/8] drm/i915: Add _PICK_EVEN_2RANGES()
(I missed this review you did before I had sent a v2.1, I will incorporate what is missing in the next version) On Mon, Jan 23, 2023 at 12:38:28PM +0200, Jani Nikula wrote: On Fri, 20 Jan 2023, Lucas De Marchi wrote: It's a constant pattern in the driver to need to use 2 ranges of MMIOs based on port, phy, pll, etc. When that happens, instead of using _PICK_EVEN(), _PICK() needs to be used. Using _PICK() is discouraged due to some reasons like: 1) It increases the code size since the array is declared in each call site Would be interesting to see what this does, and whether the compiler has the smarts to combine these within each file: -#define _PICK(__index, ...) (((const u32 []){ __VA_ARGS__ })[__index]) +#define _PICK(__index, ...) (((static const u32 []){ __VA_ARGS__ })[__index]) if the compiler is smart, it would be at least 1 per compilation unit. gcc doesn't seem smart enough to even compile it though: ../drivers/gpu/drm/i915/i915_reg_defs.h:155:52: error: expected ‘)’ before ‘{’ token 155 | #define _PICK(__index, ...) (((static const u32 []){ __VA_ARGS__ })[__index]) | ~ ^ What I'm thinking for the remaining uses of _PICK() is to be explicit and statically define them in a good .c depending on the use. Then use that in the macro. 2) Developers need to be careful not to incur an out-of-bounds array access 3) Developers need to be careful that the indexes match the table. For that it may be that the table needs to contain holes, making (1) even worse. Add a variant of _PICK_EVEN() that works with 2 ranges and selects which one to use depending on the index value. Signed-off-by: Lucas De Marchi --- drivers/gpu/drm/i915/i915_reg_defs.h | 28 1 file changed, 28 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg_defs.h b/drivers/gpu/drm/i915/i915_reg_defs.h index be43580a6979..b7ec87464d69 100644 --- a/drivers/gpu/drm/i915/i915_reg_defs.h +++ b/drivers/gpu/drm/i915/i915_reg_defs.h @@ -119,6 +119,34 @@ */ #define _PICK_EVEN(__index, __a, __b) ((__a) + (__index) * ((__b) - (__a))) +/* + * Like _PICK_EVEN(), but supports 2 ranges of evenly spaced address offsets. + * The first range is used for indexes below @__c_index, and the second + * range is used for anything above it. Example:: I'd like this to be clear about which range is used for index == __c_index, instead of saying "below" and "above". No need for the double colon :: because this isn't a kernel-doc comment. ok, what about this? * Like _PICK_EVEN(), but supports 2 ranges of evenly spaced address offsets. * @__c_index corresponds to the index in which the second range starts * to be used. Using math interval notation, the first range is used * for indexes [ 0, @__c_index), while the second range is used for * [ @__c_index, ... ). Example: + * + * #define _FOO_A 0xf000 + * #define _FOO_B 0xf004 + * #define _FOO_C 0xf008 + * #define _SUPER_FOO_A0xa000 + * #define _SUPER_FOO_B0xa100 + * #define FOO(x) _MMIO(_PICK_EVEN_RANGES(x, 3, \ The example uses a different name for the macro. yeah, that was the previous name I was using... good catch, will fix. + * _FOO_A, _FOO_B, \ + * _SUPER_FOO_A, _SUPER_FOO_B)) + * + * This expands to: + * 0: 0xf000, + * 1: 0xf004, + * 2: 0xf008, + * 3: 0xa100, With the above definitions, this would be 3: 0xa000. fixed thanks Lucas De Marchi + * 4: 0xa200, + * 5: 0xa300, + * ... + */ +#define _PICK_EVEN_2RANGES(__index, __c_index, __a, __b, __c, __d) \ + (BUILD_BUG_ON_ZERO(!__is_constexpr(__c_index)) + \ +((__index) < (__c_index) ? _PICK_EVEN(__index, __a, __b) : \ + _PICK_EVEN((__index) - (__c_index), __c, __d))) + /* * Given the arbitrary numbers in varargs, pick the 0-based __index'th number. * -- Jani Nikula, Intel Open Source Graphics Center
Re: DMA-heap driver hints
Am 24.01.23 um 04:56 schrieb James Jones: On 1/23/23 08:58, Laurent Pinchart wrote: Hi Christian, On Mon, Jan 23, 2023 at 05:29:18PM +0100, Christian König wrote: Am 23.01.23 um 14:55 schrieb Laurent Pinchart: Hi Christian, CC'ing James as I think this is related to his work on the unix device memory allocator ([1]). Thank you for including me. Sorry for not having you in initially. I wasn't aware of your previous work in this area. [1] https://lore.kernel.org/dri-devel/8b555674-1c5b-c791-4547-2ea7c16ae...@nvidia.com/ On Mon, Jan 23, 2023 at 01:37:54PM +0100, Christian König wrote: Hi guys, this is just an RFC! The last time we discussed the DMA-buf coherency problem [1] we concluded that DMA-heap first needs a better way to communicate to userspace which heap to use for a certain device. As far as I know userspace currently just hard codes that information which is certainly not desirable considering that we should have this inside the kernel as well. So what those two patches here do is to first add some dma_heap_create_device_link() and dma_heap_remove_device_link() function and then demonstrating the functionality with uvcvideo driver. The preferred DMA-heap is represented with a symlink in sysfs between the device and the virtual DMA-heap device node. I'll start with a few high-level comments/questions: - Instead of tying drivers to heaps, have you considered a system where a driver would expose constraints, and a heap would then be selected based on those constraints ? A tight coupling between heaps and drivers means downstream patches to drivers in order to use vendor-specific heaps, that sounds painful. I was wondering the same thing as well, but came to the conclusion that just the other way around is the less painful approach. From a kernel point of view, sure, it's simpler and thus less painful. From the point of view of solving the whole issue, I'm not sure :-) The problem is that there are so many driver specific constrains that I don't even know where to start from. That's where I was hoping James would have some feedback for us, based on the work he did on the Unix device memory allocator. If that's not the case, we can brainstorm this from scratch. Simon Ser's and my presentation from XDC 2020 focused entirely on this. The idea was not to try to enumerate every constraint up front, but rather to develop an extensible mechanism that would be flexible enough to encapsulate many disparate types of constraints and perform set operations on them (merging sets was the only operation we tried to solve). Simon implemented a prototype header-only library to implement the mechanism: https://gitlab.freedesktop.org/emersion/drm-constraints The links to the presentation and talk are below, along with notes from the follow-up workshop. https://lpc.events/event/9/contributions/615/attachments/704/1301/XDC_2020__Allocation_Constraints.pdf https://www.youtube.com/watch?v=HZEClOP5TIk https://paste.sr.ht/~emersion/c43b30be08bab1882f1b107402074462bba3b64a Note one of the hard parts of this was figuring out how to express a device or heap within the constraint structs. One of the better ideas proposed back then was something like heap IDs, where dma heaps would each have one, We already have that. Each dma_heap has it's own unique name. and devices could register their own heaps (or even just themselves?) with the heap subsystem and be assigned a locally-unique ID that userspace could pass around. I was more considering that we expose some kind of flag noting that a certain device needs its buffer allocated from that device to utilize all use cases. This sounds similar to what you're proposing. Perhaps a reasonable identifier is a device (major, minor) pair. Such a constraint could be expressed as a symlink for easy visualization/discoverability from userspace, but might be easier to serialize over the wire as the (major, minor) pair. I'm not clear which direction is better to express this either: As a link from heap->device, or device->heap. A constraint-based system would also, I think, be easier to extend with additional constraints in the future. - I assume some drivers will be able to support multiple heaps. How do you envision this being implemented ? I don't really see an use case for this. One use case I know of here is same-vendor GPU local memory on different GPUs. NVIDIA GPUs have certain things they can only do on local memory, certain things they can do on all memory, and certain things they can only do on memory local to another NVIDIA GPU, especially when there exists an NVLink interface between the two. So they'd ideally express different constraints for heap representing each of those. I strongly think that exposing this complexity is overkill. We have pretty much the same on AMD GPUs with XGMI, but this is so vendor specific that I'm pretty sure we shouldn't have that in
Re: [PATCH v1 10/14] drm/msm/disp/dpu: add supports of DSC encoder v1.2 engine
On 23/01/2023 20:24, Kuogee Hsieh wrote: DSC V1.2 encoder engine is newly added hardware module. This patch add support functions to configure and enable DSC V1.2 encoder engine. Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 60 +++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 23 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 23 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 371 + 6 files changed, 463 insertions(+), 17 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 28cf52b..271c29a15 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -65,6 +65,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \ disp/dpu1/dpu_hw_catalog.o \ disp/dpu1/dpu_hw_ctl.o \ disp/dpu1/dpu_hw_dsc.o \ + disp/dpu1/dpu_hw_dsc_1_2.o \ disp/dpu1/dpu_dsc_helper.o \ disp/dpu1/dpu_hw_interrupts.o \ disp/dpu1/dpu_hw_intf.o \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 7f4a439..901e317 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1821,7 +1821,7 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc, u32 initial_lines) { if (hw_dsc->ops.dsc_config) - hw_dsc->ops.dsc_config(hw_dsc, dsc, common_mode, initial_lines); + hw_dsc->ops.dsc_config(hw_dsc, dsc, common_mode, initial_lines, false); if (hw_dsc->ops.dsc_config_thresh) hw_dsc->ops.dsc_config_thresh(hw_dsc, dsc); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 978e3bd..7b0b092 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. */ @@ -11,6 +11,7 @@ #include #include #include +#include "dpu_hw_mdss.h" /** * Max hardware block count: For ex: max 12 SSPP pipes or @@ -182,6 +183,7 @@ enum { * @DPU_PINGPONG_TE2Additional tear check block for split pipes * @DPU_PINGPONG_SPLIT PP block supports split fifo * @DPU_PINGPONG_SLAVE PP block is a suitable slave for split fifo + * @DPU_PINGPONG_DSC, Display stream compression blocks * @DPU_PINGPONG_DITHER,Dither blocks * @DPU_PINGPONG_MAX */ @@ -190,10 +192,32 @@ enum { DPU_PINGPONG_TE2, DPU_PINGPONG_SPLIT, DPU_PINGPONG_SLAVE, + DPU_PINGPONG_DSC, DPU_PINGPONG_DITHER, DPU_PINGPONG_MAX }; + +/** DSC sub-blocks/features + * @DPU_DSC_OUTPUT_CTRL Supports the control of the pp id which gets + * the pixel output from this DSC. + * @DPU_DSC_HW_REV_1_1 dsc block supports dsc 1.1 only + * @DPU_DSC_HW_REV_1_2 dsc block supports dsc 1.1 and 1.2 + * @DPU_DSC_NATIVE_422_EN, Supports native422 and native420 encoding + * @DPU_DSC_ENC,DSC encoder sub block + * @DPU_DSC_CTL,DSC ctl sub block + * @DPU_DSC_MAX + */ +enum { + DPU_DSC_OUTPUT_CTRL = 0x1, + DPU_DSC_HW_REV_1_1, + DPU_DSC_HW_REV_1_2, + DPU_DSC_NATIVE_422_EN, + DPU_DSC_ENC, + DPU_DSC_CTL, + DPU_DSC_MAX +}; + /** * CTL sub-blocks * @DPU_CTL_SPLIT_DISPLAY:CTL supports video mode split display @@ -276,15 +300,6 @@ enum { }; /** - * DSC features - * @DPU_DSC_OUTPUT_CTRL Configure which PINGPONG block gets - *the pixel output from this DSC. - */ -enum { - DPU_DSC_OUTPUT_CTRL = 0x1, -}; - Any reason for this move? -/** * MACRO DPU_HW_BLK_INFO - information of HW blocks inside DPU * @name: string name for debug purposes * @id:enum identifying this block @@ -346,6 +361,14 @@ struct dpu_pp_blk { }; /** + * struct dpu_dsc_blk : DSC Encoder sub-blk information + * @info: HW register and features supported by this sub-blk + */ +struct dpu_dsc_blk { + DPU_HW_SUBBLK_INFO; +}; + +/** * enum dpu_qos_lut_usage - define QoS LUT use cases */ enum dpu_qos_lut_usage { @@ -403,6 +426,7 @@ struct dpu_rotation_cfg { * @pixel_ram_size size of latency hiding and de-tiling buffer in bytes * @max_hdeci_exp max horizontal decimation supported (max is 2^value) * @max_vdeci_exp max vertical decimation
Re: [PATCH 2/2] drm: lcdif: Add i.MX93 LCDIF support
On Mon, 2023-01-23 at 09:13 +0100, Lothar Waßmann wrote: > Hi, Hi, > > On Mon, 23 Jan 2023 15:23:58 +0800 Liu Ying wrote: > > The LCDIF embedded in i.MX93 SoC is essentially the same to those > > in i.MX8mp SoC. However, i.MX93 LCDIF may connect with MIPI DSI > > controller through LCDIF cross line pattern(controlled by mediamix > > blk-ctrl) or connect with LVDS display bridge(LDB) directly or a > > parallel display(also through mediamix blk-ctrl), so add multiple > > encoders(with DRM_MODE_ENCODER_NONE encoder type) support in the > > LCDIF DRM driver and find a bridge to attach the relevant encoder's > > chain when needed. While at it, derive lcdif_crtc_state structure > > from drm_crtc_state structure to introduce bus_format and bus_flags > > states so that the next downstream bridges may use consistent bus > > format and bus flags. > > > > Signed-off-by: Liu Ying > > --- > > drivers/gpu/drm/mxsfb/lcdif_drv.c | 73 +-- > > drivers/gpu/drm/mxsfb/lcdif_drv.h | 6 +- > > drivers/gpu/drm/mxsfb/lcdif_kms.c | 206 > > -- > > 3 files changed, 208 insertions(+), 77 deletions(-) > > > > diff --git a/drivers/gpu/drm/mxsfb/lcdif_drv.c > > b/drivers/gpu/drm/mxsfb/lcdif_drv.c > > index cc2ceb301b96..4d41f6b6eb14 100644 > > --- a/drivers/gpu/drm/mxsfb/lcdif_drv.c > > +++ b/drivers/gpu/drm/mxsfb/lcdif_drv.c > > @@ -9,13 +9,16 @@ > > #include > > #include > > #include > > +#include > > #include > > +#include > > #include > > #include > > > > #include > > #include > > #include > > +#include > > #include > > #include > > #include > > @@ -38,21 +41,70 @@ static const struct > > drm_mode_config_helper_funcs lcdif_mode_config_helpers = { > > .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm, > > }; > > > > +static const struct drm_encoder_funcs lcdif_encoder_funcs = { > > + .destroy = drm_encoder_cleanup, > > +}; > > + > > static int lcdif_attach_bridge(struct lcdif_drm_private *lcdif) > > { > > - struct drm_device *drm = lcdif->drm; > > + struct device *dev = lcdif->drm->dev; > > + struct device_node *ep; > > struct drm_bridge *bridge; > > int ret; > > > > - bridge = devm_drm_of_get_bridge(drm->dev, drm->dev->of_node, 0, > > 0); > > - if (IS_ERR(bridge)) > > - return PTR_ERR(bridge); > > - > > - ret = drm_bridge_attach(>encoder, bridge, NULL, 0); > > - if (ret) > > - return dev_err_probe(drm->dev, ret, "Failed to attach > > bridge\n"); > > - > > - lcdif->bridge = bridge; > > + for_each_endpoint_of_node(dev->of_node, ep) { > > + struct device_node *remote; > > + struct of_endpoint of_ep; > > + struct drm_encoder *encoder; > > + > > + remote = of_graph_get_remote_port_parent(ep); > > + if (!remote || !of_device_is_available(remote)) { > > '!remote ||' is redundant, since of_device_is_available already > checks > for a NULL pointer. of_device_is_available() does check for a NULL pointer when it calls __of_device_is_available() (after it takes devtree_lock raw spinlock and then releases devtree_lock). So, if remote is NULL, '!remote ||' exits the if clause a bit earlier without calling of_device_is_available() to take/release devtree_lock, which means a little bit better performance. But, people may say that the performance gain is trivial. drm_of_component_probe() in drm_of.c also checks '!remote' before checking '!of_device_is_available(remote)'. Do you still think that both drm_of_component_probe() and lcdif_attach_bridge() should drop '!remote ||'? > > [...] > > > diff --git a/drivers/gpu/drm/mxsfb/lcdif_kms.c > > b/drivers/gpu/drm/mxsfb/lcdif_kms.c > > index 262bc43b1079..ba36447ed900 100644 > > --- a/drivers/gpu/drm/mxsfb/lcdif_kms.c > > +++ b/drivers/gpu/drm/mxsfb/lcdif_kms.c > > [...] > > @@ -529,6 +580,46 @@ static void lcdif_crtc_atomic_disable(struct > > drm_crtc *crtc, > > pm_runtime_put_sync(drm->dev); > > } > > > > +static void lcdif_crtc_reset(struct drm_crtc *crtc) > > +{ > > + struct lcdif_crtc_state *state; > > + > > + if (crtc->state) > > + __drm_atomic_helper_crtc_destroy_state(crtc->state); > > + > > + kfree(to_lcdif_crtc_state(crtc->state)); > > > > If crtc-state can be NULL at this point, this will only work as long > as > 'base' is the first member of the lcdif_crtc_state struct (which > currently is the case, but there is no guarantee that this will > always > be this way), otherwise the if clause above is not needed. crtc->state can be NULL when e.g. at driver load time, like kerneldoc for drm_atomic_helper_crtc_reset() mentions. I may add a comment for the 'base' member to note that it should be always the first member of the lcdif_crtc_state structure. Do you think that will be ok? Thanks, Liu Ying > > > > Lothar Waßmann
Re: DMA-heap driver hints
Am 24.01.23 um 06:19 schrieb John Stultz: On Mon, Jan 23, 2023 at 8:29 AM Christian König wrote: Am 23.01.23 um 14:55 schrieb Laurent Pinchart: - I assume some drivers will be able to support multiple heaps. How do you envision this being implemented ? I don't really see an use case for this. We do have some drivers which say: for this use case you can use whatever you want, but for that use case you need to use specific memory (scan out on GPUs for example works like this). [snipping the constraints argument, which I agree with] What we do have is compatibility between heaps. E.g. a CMA heap is usually compatible with the system heap or might even be a subset of another CMA heap. But I wanted to add that as next step to the heaps framework itself. So the difficult question is how is userland supposed to know which heap is compatible with which? The heaps should know which other heap they are compatible with. E.g. the CMA heap should have a link to the system heap because it can handle all system memory allocations as well. If we have a specialized CMA heap (for example for 32bit DMA) it should have a link to the general CMA heap. If you have two devices, one that points to heap "foo" and the other points to heap "bar", how does userland know that "foo" satisfies the constraints of "bar" but "bar" doesn't satisfy the constraints of "foo". (foo ="cma", bar="system") I think it would be much better for device 1 to list "foo" and device 2 to list "foo" and "bar", so you can find that "foo" is the common heap which will solve both devices' needs. I think that this would be a rather bad idea because then all devices need to know about all the possible different heaps they are compatible with. For example a device which knows that it's compatible with system memory should only expose that information. That a CMA heap is also compatible with system memory is irrelevant for this device and should be handled between the CMA and system heap. - Devices could have different constraints based on particular configurations. For instance, a device may require specific memory layout for multi-planar YUV formats only (as in allocating the Y and C planes of NV12 from different memory banks). A dynamic API may thus be needed (but may also be very painful to use from userspace). Uff, good to know. But I'm not sure how to expose stuff like that. Yeah. These edge cases are really hard to solve generically. And single devices that have separate constraints for different uses are also not going to be solvable with a simple linking approach. But I do wonder if a generic solution to all cases is needed (especially if it really isn't possible)? If we leave the option for gralloc like omniscient device-specific userland policy, those edge cases can be handled by those devices that can't run generic logic. And those devices just won't be able to be supported by generic distros, hopefully motivating future designs to have less odd constraints? Potentially yes, but I think that anything more complex than "please allocate from this piece of memory for me" is not something which should be handled inside the device independent framework. Especially device specific memory and allocation constrains (e.g. things like don't put those two things on the same memory channel) is *not* something we should have in an inter device framework. In those cases we should just be able to say that an allocation should be made from a specific device and then let the device specific drivers deal with the constrain. Regards, Christian. thanks -john
Re: [PATCH v6 3/5] drm/tidss: Add support to configure OLDI mode for am625-dss.
Hi Tomi, Thanks for reviewing the patch series. I have implemented the most of your suggestions, but for the others, I needed to clarify things. I have made some comments there. On 20-Dec-22 18:22, Tomi Valkeinen wrote: Hi, On 19/11/2022 19:30, Aradhya Bhatia wrote: The newer version of DSS (AM625-DSS) has 2 OLDI TXes at its disposal. These can be configured to support the following modes: 1. OLDI_SINGLE_LINK_SINGLE_MODE Single Output over OLDI 0. +--+ +-+ +---+ | | | | | | | CRTC +--->+ ENCODER +->| PANEL | | | | | | | +--+ +-+ +---+ 2. OLDI_SINGLE_LINK_CLONE_MODE Duplicate Output over OLDI 0 and 1. +--+ +-+ +---+ | | | | | | | CRTC +---+--->| ENCODER +->| PANEL | | | | | | | | +--+ | +-+ +---+ | | +-+ +---+ | | | | | +--->| ENCODER +->| PANEL | | | | | +-+ +---+ 3. OLDI_DUAL_LINK_MODE Combined Output over OLDI 0 and 1. +--+ +-+ +---+ | | | +->| | | CRTC +--->+ ENCODER | | PANEL | | | | +->| | +--+ +-+ +---+ Following the above pathways for different modes, 2 encoder/panel-bridge pipes get created for clone mode, and 1 pipe in cases of single link and dual link mode. Add support for confguring the OLDI modes using OF and LVDS DRM helper functions. Signed-off-by: Aradhya Bhatia --- drivers/gpu/drm/tidss/tidss_dispc.c | 12 ++ drivers/gpu/drm/tidss/tidss_dispc.h | 9 ++ drivers/gpu/drm/tidss/tidss_drv.h | 3 + drivers/gpu/drm/tidss/tidss_encoder.c | 4 +- drivers/gpu/drm/tidss/tidss_encoder.h | 3 +- drivers/gpu/drm/tidss/tidss_kms.c | 188 +++--- 6 files changed, 198 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c index dbc6a5b617ca..472226a83251 100644 --- a/drivers/gpu/drm/tidss/tidss_dispc.c +++ b/drivers/gpu/drm/tidss/tidss_dispc.c @@ -365,6 +365,8 @@ struct dispc_device { struct dss_vp_data vp_data[TIDSS_MAX_VPS]; + enum dispc_oldi_modes oldi_mode; + u32 *fourccs; u32 num_fourccs; @@ -1967,6 +1969,16 @@ const u32 *dispc_plane_formats(struct dispc_device *dispc, unsigned int *len) return dispc->fourccs; } +int dispc_set_oldi_mode(struct dispc_device *dispc, + enum dispc_oldi_modes oldi_mode) +{ + WARN_ON(!dispc); This feels unnecessary. Is there even a theoretical case where we could get dispc == NULL? + + dispc->oldi_mode = oldi_mode; + + return 0; This function could as well be void function. > +} + static s32 pixinc(int pixels, u8 ps) { if (pixels == 1) diff --git a/drivers/gpu/drm/tidss/tidss_dispc.h b/drivers/gpu/drm/tidss/tidss_dispc.h index 51db500590ee..e76a7599b544 100644 --- a/drivers/gpu/drm/tidss/tidss_dispc.h +++ b/drivers/gpu/drm/tidss/tidss_dispc.h @@ -64,6 +64,14 @@ enum dispc_dss_subrevision { DISPC_AM625, }; +enum dispc_oldi_modes { + OLDI_MODE_OFF, /* OLDI turned off / tied off in IP. */ + OLDI_SINGLE_LINK_SINGLE_MODE, /* Single Output over OLDI 0. */ + OLDI_SINGLE_LINK_CLONE_MODE, /* Duplicate Output over OLDI 0 and 1. */ + OLDI_DUAL_LINK_MODE, /* Combined Output over OLDI 0 and 1. */ + OLDI_MODE_UNSUPPORTED, /* Unsupported OLDI Mode */ +}; What is the difference with MODE_OFF and MODE_UNSUPPORTED? Is MODE_UNSUPPORTED for cases where, e.g., the DT setup is wrong and the driver should return an error? The code doesn't quite do that, it prints an error but then continues. Yes, OLDI_MODE_UNSUPPORTED is for the cases where DT setup is wrong. I have not exited in such a cases with an error, because then the driver will never have a chance to setup the 2nd pipeline (DPI) even if all the DT requirements are met. struct dispc_features { int min_pclk_khz; int max_pclk_khz[DISPC_VP_MAX_BUS_TYPE]; @@ -133,6 +141,7 @@ int dispc_plane_setup(struct dispc_device *dispc, u32 hw_plane, u32 hw_videoport); int dispc_plane_enable(struct dispc_device *dispc, u32 hw_plane, bool enable); const u32 *dispc_plane_formats(struct dispc_device *dispc, unsigned int *len); +int dispc_set_oldi_mode(struct dispc_device *dispc, enum dispc_oldi_modes oldi_mode); int dispc_init(struct tidss_device *tidss); void dispc_remove(struct tidss_device *tidss); diff --git a/drivers/gpu/drm/tidss/tidss_drv.h b/drivers/gpu/drm/tidss/tidss_drv.h index 0ce7ee5ccd5b..58892f065c16 100644 --- a/drivers/gpu/drm/tidss/tidss_drv.h +++ b/drivers/gpu/drm/tidss/tidss_drv.h @@ -13,6 +13,9 @@ #define
Re: [PATCH 1/2] drm: bridge: dw-mipi-dsi: Handle NO_EOT_PACKET mode
On Tue, 24 Jan 2023 at 01:49, Sam Ravnborg wrote: > > Hi Jagan. > > One small drive-by comment. > > On Tue, Jan 24, 2023 at 12:16:46AM +0530, Jagan Teki wrote: > > Many downstream bridges or panels followed by dw-mipi-dsi were > > using MIPI_DSI_MODE_NO_EOT_PACKET. > > > > So, handle the EOTP bits accordingly in the dw-mipi-dsi host. > > > > Signed-off-by: Jagan Teki > > --- > > drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 8 +++- > > 1 file changed, 7 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c > > b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c > > index b2efecf7d160..47bd69d5ac99 100644 > > --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c > > +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c > > @@ -664,7 +664,13 @@ static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi > > *dsi, > > > > static void dw_mipi_dsi_packet_handler_config(struct dw_mipi_dsi *dsi) > > { > > - dsi_write(dsi, DSI_PCKHDL_CFG, CRC_RX_EN | ECC_RX_EN | BTA_EN); > > + u32 val; > > + > > + val = CRC_RX_EN | ECC_RX_EN | BTA_EN | EOTP_TX_EN; > > + if (dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET) > > + val &= ~EOTP_TX_EN; > > I had to look twice because the bit is set, and then maybe cleared. > > val = CRC_RX_EN | ECC_RX_EN | BTA_EN | EOTP_TX_EN; > if (!(dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)) > val |= EOTP_TX_EN; > ? What I understand is if NO_EOT means we need to disable EOTP_TX_EN bit so the logic in the patch does the same. Enable the EOTP_TX_EN by default and disable it if NO_EOT mode set. Jagan.
Re: [LSF/MM/BPF proposal]: Physr discussion
On 1/23/23 11:47, Bart Van Assche wrote: > On 1/23/23 05:44, Jason Gunthorpe wrote: >> I've gone from quite a different starting point - I've been working >> DMA API upwards, so what does the dma_map_XX look like, what APIs do >> we need to support the dma_map_ops implementations to iterate/etc, how >> do we form and return the dma mapped list, how does P2P, with all the >> checks, actually work, etc. These help inform what we want from the >> "phyr" as an API. > > I'm interested in this topic. I'm wondering whether eliminating > scatterlists could help to make the block layer faster. > > Thanks, > > Bart. > I think it will be very interesting to discuss this in great detail and come up with the plan. +1 from me. -ck
Assertion failure in i915 intel_display.c#assert_plane() after resume from hibernation
Hi A user in Debian, cc'ed reporte the following issue when resuming from hibernation, tested as well on recent 6.1.7 kernel, context see https://bugs.debian.org/971068 > Can repro on the sid kernel, uname -a of > Linux nabtop 6.1.0-2-686-pae #1 SMP PREEMPT_DYNAMIC Debian 6.1.7-1 > (2023-01-18) i686 GNU/Linux > > Log below. Backtrace is only trivially different. > > Best, > наб > > -- >8 -- > Jan 22 14:06:46 nabtop kernel: OOM killer disabled. > Jan 22 14:06:46 nabtop kernel: PM: hibernation: Marking nosave pages: [mem > 0x-0x0fff] > Jan 22 14:06:46 nabtop kernel: PM: hibernation: Marking nosave pages: [mem > 0x0009f000-0x000f] > Jan 22 14:06:46 nabtop kernel: PM: hibernation: Marking nosave pages: [mem > 0xb5aa1000-0xb5aa6fff] > Jan 22 14:06:46 nabtop kernel: PM: hibernation: Marking nosave pages: [mem > 0xb5bba000-0xb5c0efff] > Jan 22 14:06:46 nabtop kernel: PM: hibernation: Marking nosave pages: [mem > 0xb5d08000-0xb5f0efff] > Jan 22 14:06:46 nabtop kernel: PM: hibernation: Marking nosave pages: [mem > 0xb5f18000-0xb5f1efff] > Jan 22 14:06:46 nabtop kernel: PM: hibernation: Marking nosave pages: [mem > 0xb5f65000-0xb5f9efff] > Jan 22 14:06:46 nabtop kernel: PM: hibernation: Marking nosave pages: [mem > 0xb5fe1000-0xb5ffefff] > Jan 22 14:06:46 nabtop kernel: PM: hibernation: Marking nosave pages: [mem > 0xb600-0x] > Jan 22 14:06:46 nabtop kernel: PM: hibernation: Basic memory bitmaps created > Jan 22 14:06:46 nabtop kernel: PM: hibernation: Preallocating image memory > Jan 22 14:06:46 nabtop kernel: PM: hibernation: Allocated 183519 pages for > snapshot > Jan 22 14:06:46 nabtop kernel: PM: hibernation: Allocated 734076 kbytes in > 0.70 seconds (1048.68 MB/s) > Jan 22 14:06:46 nabtop kernel: Freezing remaining freezable tasks ... > (elapsed 0.001 seconds) done. > Jan 22 14:06:46 nabtop kernel: wifi1: deauthenticating from de:0d:17:ad:80:55 > by local choice (Reason: 3=DEAUTH_LEAVING) > Jan 22 14:06:46 nabtop kernel: ACPI: EC: interrupt blocked > Jan 22 14:06:46 nabtop kernel: ACPI: PM: Preparing to enter system sleep > state S4 > Jan 22 14:06:46 nabtop kernel: ACPI: EC: event blocked > Jan 22 14:06:46 nabtop kernel: ACPI: EC: EC stopped > Jan 22 14:06:46 nabtop kernel: ACPI: PM: Saving platform NVS memory > Jan 22 14:06:46 nabtop kernel: Disabling non-boot CPUs ... > Jan 22 14:06:46 nabtop kernel: smpboot: CPU 1 is now offline > Jan 22 14:06:46 nabtop kernel: PM: hibernation: Creating image: > Jan 22 14:06:46 nabtop kernel: PM: hibernation: Need to copy 175700 pages > Jan 22 14:06:46 nabtop kernel: PM: hibernation: Normal pages needed: 57765 + > 1024, available pages: 167322 > Jan 22 14:06:46 nabtop kernel: ACPI: PM: Restoring platform NVS memory > Jan 22 14:06:46 nabtop kernel: ACPI: EC: EC started > Jan 22 14:06:46 nabtop kernel: Enabling non-boot CPUs ... > Jan 22 14:06:46 nabtop kernel: x86: Booting SMP configuration: > Jan 22 14:06:46 nabtop kernel: smpboot: Booting Node 0 Processor 1 APIC 0x1 > Jan 22 14:06:46 nabtop kernel: CPU1 is up > Jan 22 14:06:46 nabtop kernel: ACPI: PM: Waking up from system sleep state S4 > Jan 22 14:06:46 nabtop kernel: ACPI: EC: interrupt unblocked > Jan 22 14:06:46 nabtop kernel: ACPI: EC: event unblocked > Jan 22 14:06:46 nabtop kernel: usb usb1: root hub lost power or was reset > Jan 22 14:06:46 nabtop kernel: usb usb2: root hub lost power or was reset > Jan 22 14:06:46 nabtop kernel: usb usb4: root hub lost power or was reset > Jan 22 14:06:46 nabtop kernel: usb usb3: root hub lost power or was reset > Jan 22 14:06:46 nabtop kernel: usb usb6: root hub lost power or was reset > Jan 22 14:06:46 nabtop kernel: usb usb7: root hub lost power or was reset > Jan 22 14:06:46 nabtop kernel: usb usb8: root hub lost power or was reset > Jan 22 14:06:46 nabtop kernel: usb usb5: root hub lost power or was reset > Jan 22 14:06:46 nabtop kernel: sd 0:0:0:0: [sda] Starting disk > Jan 22 14:06:46 nabtop kernel: iwlwifi :08:00.0: Radio type=0x1-0x2-0x0 > Jan 22 14:06:46 nabtop kernel: iwlwifi :08:00.0: Radio type=0x1-0x2-0x0 > Jan 22 14:06:46 nabtop kernel: [ cut here ] > Jan 22 14:06:46 nabtop kernel: primary B assertion failure (expected off, > current on) > Jan 22 14:06:46 nabtop kernel: WARNING: CPU: 0 PID: 1038 at > drivers/gpu/drm/i915/display/intel_display.c:476 assert_plane+0x9f/0xb0 [i915] > Jan 22 14:06:46 nabtop kernel: Modules linked in: ghash_generic gf128mul gcm > ccm algif_aead des_generic libdes ecb algif_skcipher bnep cmac md4 algif_hash > af_alg binfmt_misc btusb btrtl btbcm btintel btmtk bluetooth > jitterentropy_rng sha512_generic ctr drbg joydev ansi_cprng ecdh_generic ecc > iwldvm mac80211 libarc4 iTCO_wdt intel_pmc_bxt snd_hda_codec_conexant > iTCO_vendor_support uvcvideo watchdog snd_hda_codec_generic ledtrig_audio > videobuf2_vmalloc videobuf2_memops i915 videobuf2_v4l2 nls_ascii > snd_hda_intel iwlwifi videobuf2_common snd_intel_dspcfg drm_buddy > snd_intel_sdw_acpi
[PATCH v3 5/6] drm/rockchip: vop2: add support for the rgb output block
The Rockchip VOP2 features an internal RGB output block, which can be attached any video port of the VOP2. Add support for this output block. Signed-off-by: Michael Riesch --- v3: - fix commit messages (still assumed video port 2) - fix condition to make 0 a valid video port v2: - move away from wrong assumption that the RGB block is always connected to video port 2 -> check devicetree to find RGB block drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 44 1 file changed, 44 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index 06fcdfa7b885..f38ffd0ccd9f 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -39,6 +39,7 @@ #include "rockchip_drm_gem.h" #include "rockchip_drm_fb.h" #include "rockchip_drm_vop2.h" +#include "rockchip_rgb.h" /* * VOP2 architecture @@ -212,6 +213,9 @@ struct vop2 { struct clk *hclk; struct clk *aclk; + /* optional internal rgb encoder */ + struct rockchip_rgb *rgb; + /* must be put at the end of the struct */ struct vop2_win win[]; }; @@ -2393,6 +2397,25 @@ static void vop2_destroy_crtcs(struct vop2 *vop2) } } +static int vop2_find_rgb_encoder(struct vop2 *vop2) +{ + struct device_node *node = vop2->dev->of_node; + struct device_node *endpoint; + int i; + + for (i = 0; i < vop2->data->nr_vps; i++) { + endpoint = of_graph_get_endpoint_by_regs(node, i, +ROCKCHIP_VOP2_EP_RGB0); + if (!endpoint) + continue; + + of_node_put(endpoint); + return i; + } + + return -ENOENT; +} + static struct reg_field vop2_cluster_regs[VOP2_WIN_MAX_REG] = { [VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0), [VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5), @@ -2698,11 +2721,29 @@ static int vop2_bind(struct device *dev, struct device *master, void *data) if (ret) return ret; + ret = vop2_find_rgb_encoder(vop2); + if (ret >= 0) { + vop2->rgb = rockchip_rgb_init(dev, >vps[ret].crtc, + vop2->drm, ret); + if (IS_ERR(vop2->rgb)) { + if (PTR_ERR(vop2->rgb) == -EPROBE_DEFER) { + ret = PTR_ERR(vop2->rgb); + goto err_crtcs; + } + vop2->rgb = NULL; + } + } + rockchip_drm_dma_init_device(vop2->drm, vop2->dev); pm_runtime_enable(>dev); return 0; + +err_crtcs: + vop2_destroy_crtcs(vop2); + + return ret; } static void vop2_unbind(struct device *dev, struct device *master, void *data) @@ -2711,6 +2752,9 @@ static void vop2_unbind(struct device *dev, struct device *master, void *data) pm_runtime_disable(dev); + if (vop2->rgb) + rockchip_rgb_fini(vop2->rgb); + vop2_destroy_crtcs(vop2); } -- 2.30.2
[PATCH v3 4/6] drm/rockchip: vop2: use symmetric function pair vop2_{create, destroy}_crtcs
Let the function name vop2_create_crtcs reflect that the function creates multiple CRTCS. Also, use a symmetric function pair to create and destroy the CRTCs and the corresponding planes. Signed-off-by: Michael Riesch --- v3: - no changes v2: - no changes drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 31 ++-- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index 374ef821b453..06fcdfa7b885 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -2246,7 +2246,7 @@ static struct vop2_video_port *find_vp_without_primary(struct vop2 *vop2) #define NR_LAYERS 6 -static int vop2_create_crtc(struct vop2 *vop2) +static int vop2_create_crtcs(struct vop2 *vop2) { const struct vop2_data *vop2_data = vop2->data; struct drm_device *drm = vop2->drm; @@ -2372,15 +2372,25 @@ static int vop2_create_crtc(struct vop2 *vop2) return 0; } -static void vop2_destroy_crtc(struct drm_crtc *crtc) +static void vop2_destroy_crtcs(struct vop2 *vop2) { - of_node_put(crtc->port); + struct drm_device *drm = vop2->drm; + struct list_head *crtc_list = >mode_config.crtc_list; + struct list_head *plane_list = >mode_config.plane_list; + struct drm_crtc *crtc, *tmpc; + struct drm_plane *plane, *tmpp; + + list_for_each_entry_safe(plane, tmpp, plane_list, head) + drm_plane_cleanup(plane); /* * Destroy CRTC after vop2_plane_destroy() since vop2_disable_plane() * references the CRTC. */ - drm_crtc_cleanup(crtc); + list_for_each_entry_safe(crtc, tmpc, crtc_list, head) { + of_node_put(crtc->port); + drm_crtc_cleanup(crtc); + } } static struct reg_field vop2_cluster_regs[VOP2_WIN_MAX_REG] = { @@ -2684,7 +2694,7 @@ static int vop2_bind(struct device *dev, struct device *master, void *data) if (ret) return ret; - ret = vop2_create_crtc(vop2); + ret = vop2_create_crtcs(vop2); if (ret) return ret; @@ -2698,19 +2708,10 @@ static int vop2_bind(struct device *dev, struct device *master, void *data) static void vop2_unbind(struct device *dev, struct device *master, void *data) { struct vop2 *vop2 = dev_get_drvdata(dev); - struct drm_device *drm = vop2->drm; - struct list_head *plane_list = >mode_config.plane_list; - struct list_head *crtc_list = >mode_config.crtc_list; - struct drm_crtc *crtc, *tmpc; - struct drm_plane *plane, *tmpp; pm_runtime_disable(dev); - list_for_each_entry_safe(plane, tmpp, plane_list, head) - drm_plane_cleanup(plane); - - list_for_each_entry_safe(crtc, tmpc, crtc_list, head) - vop2_destroy_crtc(crtc); + vop2_destroy_crtcs(vop2); } const struct component_ops vop2_component_ops = { -- 2.30.2
[PATCH v3 6/6] arm64: dts: rockchip: add pinctrls for 16-bit/18-bit rgb interface to rk356x
The rk3568-pinctrl.dtsi only defines the 24-bit RGB interface. Add separate nodes for the 16-bit and 18-bit version, respectively. While at it, split off the clock/sync signals from the data signals. The exact mapping of the data pins was discussed here: https://lore.kernel.org/linux-rockchip/f33a0488-528c-99de-3279-3c0346a03...@wolfvision.net/T/ Signed-off-by: Michael Riesch --- v3: - no changes v2: - no changes .../boot/dts/rockchip/rk3568-pinctrl.dtsi | 94 +++ 1 file changed, 94 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi b/arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi index 8f90c66dd9e9..0a979bfb63d9 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi @@ -3117,4 +3117,98 @@ tsadc_pin: tsadc-pin { <0 RK_PA1 0 _pull_none>; }; }; + + lcdc { + /omit-if-no-ref/ + lcdc_clock: lcdc-clock { + rockchip,pins = + /* lcdc_clk */ + <3 RK_PA0 1 _pull_none>, + /* lcdc_den */ + <3 RK_PC3 1 _pull_none>, + /* lcdc_hsync */ + <3 RK_PC1 1 _pull_none>, + /* lcdc_vsync */ + <3 RK_PC2 1 _pull_none>; + }; + + /omit-if-no-ref/ + lcdc_data16: lcdc-data16 { + rockchip,pins = + /* lcdc_d3 */ + <2 RK_PD3 1 _pull_none>, + /* lcdc_d4 */ + <2 RK_PD4 1 _pull_none>, + /* lcdc_d5 */ + <2 RK_PD5 1 _pull_none>, + /* lcdc_d6 */ + <2 RK_PD6 1 _pull_none>, + /* lcdc_d7 */ + <2 RK_PD7 1 _pull_none>, + /* lcdc_d10 */ + <3 RK_PA3 1 _pull_none>, + /* lcdc_d11 */ + <3 RK_PA4 1 _pull_none>, + /* lcdc_d12 */ + <3 RK_PA5 1 _pull_none>, + /* lcdc_d13 */ + <3 RK_PA6 1 _pull_none>, + /* lcdc_d14 */ + <3 RK_PA7 1 _pull_none>, + /* lcdc_d15 */ + <3 RK_PB0 1 _pull_none>, + /* lcdc_d19 */ + <3 RK_PB4 1 _pull_none>, + /* lcdc_d20 */ + <3 RK_PB5 1 _pull_none>, + /* lcdc_d21 */ + <3 RK_PB6 1 _pull_none>, + /* lcdc_d22 */ + <3 RK_PB7 1 _pull_none>, + /* lcdc_d23 */ + <3 RK_PC0 1 _pull_none>; + }; + + /omit-if-no-ref/ + lcdc_data18: lcdc-data18 { + rockchip,pins = + /* lcdc_d2 */ + <2 RK_PD2 1 _pull_none>, + /* lcdc_d3 */ + <2 RK_PD3 1 _pull_none>, + /* lcdc_d4 */ + <2 RK_PD4 1 _pull_none>, + /* lcdc_d5 */ + <2 RK_PD5 1 _pull_none>, + /* lcdc_d6 */ + <2 RK_PD6 1 _pull_none>, + /* lcdc_d7 */ + <2 RK_PD7 1 _pull_none>, + /* lcdc_d10 */ + <3 RK_PA3 1 _pull_none>, + /* lcdc_d11 */ + <3 RK_PA4 1 _pull_none>, + /* lcdc_d12 */ + <3 RK_PA5 1 _pull_none>, + /* lcdc_d13 */ + <3 RK_PA6 1 _pull_none>, + /* lcdc_d14 */ + <3 RK_PA7 1 _pull_none>, + /* lcdc_d15 */ + <3 RK_PB0 1 _pull_none>, + /* lcdc_d18 */ + <3 RK_PB3 1 _pull_none>, + /* lcdc_d19 */ + <3 RK_PB4 1 _pull_none>, + /* lcdc_d20 */ + <3 RK_PB5 1 _pull_none>, +
[PATCH v3 3/6] drm/rockchip: rgb: add video_port parameter to init function
The VOP2 driver has more than one video port, hence the hard-coded port id will not work anymore. Add an extra parameter for the video port id to the rockchip_rgb_init function. Signed-off-by: Michael Riesch --- v3: - no changes v2: - no changes drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 2 +- drivers/gpu/drm/rockchip/rockchip_rgb.c | 9 + drivers/gpu/drm/rockchip/rockchip_rgb.h | 6 -- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index fa1f4ee6d195..5d18dea5c8d6 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -2221,7 +2221,7 @@ static int vop_bind(struct device *dev, struct device *master, void *data) goto err_disable_pm_runtime; if (vop->data->feature & VOP_FEATURE_INTERNAL_RGB) { - vop->rgb = rockchip_rgb_init(dev, >crtc, vop->drm_dev); + vop->rgb = rockchip_rgb_init(dev, >crtc, vop->drm_dev, 0); if (IS_ERR(vop->rgb)) { ret = PTR_ERR(vop->rgb); goto err_disable_pm_runtime; diff --git a/drivers/gpu/drm/rockchip/rockchip_rgb.c b/drivers/gpu/drm/rockchip/rockchip_rgb.c index 5971df4302f2..c677b71ae516 100644 --- a/drivers/gpu/drm/rockchip/rockchip_rgb.c +++ b/drivers/gpu/drm/rockchip/rockchip_rgb.c @@ -72,7 +72,8 @@ struct drm_encoder_helper_funcs rockchip_rgb_encoder_helper_funcs = { struct rockchip_rgb *rockchip_rgb_init(struct device *dev, struct drm_crtc *crtc, - struct drm_device *drm_dev) + struct drm_device *drm_dev, + int video_port) { struct rockchip_rgb *rgb; struct drm_encoder *encoder; @@ -90,7 +91,7 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev, rgb->dev = dev; rgb->drm_dev = drm_dev; - port = of_graph_get_port_by_id(dev->of_node, 0); + port = of_graph_get_port_by_id(dev->of_node, video_port); if (!port) return ERR_PTR(-EINVAL); @@ -103,8 +104,8 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev, continue; child_count++; - ret = drm_of_find_panel_or_bridge(dev->of_node, 0, endpoint_id, - , ); + ret = drm_of_find_panel_or_bridge(dev->of_node, video_port, + endpoint_id, , ); if (!ret) { of_node_put(endpoint); break; diff --git a/drivers/gpu/drm/rockchip/rockchip_rgb.h b/drivers/gpu/drm/rockchip/rockchip_rgb.h index 27b9635124bc..1bd4e20e91eb 100644 --- a/drivers/gpu/drm/rockchip/rockchip_rgb.h +++ b/drivers/gpu/drm/rockchip/rockchip_rgb.h @@ -8,12 +8,14 @@ #ifdef CONFIG_ROCKCHIP_RGB struct rockchip_rgb *rockchip_rgb_init(struct device *dev, struct drm_crtc *crtc, - struct drm_device *drm_dev); + struct drm_device *drm_dev, + int video_port); void rockchip_rgb_fini(struct rockchip_rgb *rgb); #else static inline struct rockchip_rgb *rockchip_rgb_init(struct device *dev, struct drm_crtc *crtc, -struct drm_device *drm_dev) +struct drm_device *drm_dev, +int video_port) { return NULL; } -- 2.30.2
[PATCH v3 2/6] drm/rockchip: rgb: embed drm_encoder into rockchip_encoder
Commit 540b8f271e53 ("drm/rockchip: Embed drm_encoder into rockchip_decoder") provides the means to pass the endpoint ID to the VOP2 driver, which sets the interface MUX accordingly. However, this step has not yet been carried out for the RGB output block. Embed the drm_encoder structure into the rockchip_encoder structure and set the endpoint ID correctly. Signed-off-by: Michael Riesch --- v3: - no changes v2: - use endpoint id from device tree instead of hardcoded value drivers/gpu/drm/rockchip/rockchip_rgb.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_rgb.c b/drivers/gpu/drm/rockchip/rockchip_rgb.c index 75eb7cca3d82..5971df4302f2 100644 --- a/drivers/gpu/drm/rockchip/rockchip_rgb.c +++ b/drivers/gpu/drm/rockchip/rockchip_rgb.c @@ -22,13 +22,11 @@ #include "rockchip_drm_vop.h" #include "rockchip_rgb.h" -#define encoder_to_rgb(c) container_of(c, struct rockchip_rgb, encoder) - struct rockchip_rgb { struct device *dev; struct drm_device *drm_dev; struct drm_bridge *bridge; - struct drm_encoder encoder; + struct rockchip_encoder encoder; struct drm_connector connector; int output_mode; }; @@ -125,7 +123,7 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev, return ERR_PTR(ret); } - encoder = >encoder; + encoder = >encoder.encoder; encoder->possible_crtcs = drm_crtc_mask(crtc); ret = drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_NONE); @@ -161,6 +159,8 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev, goto err_free_encoder; } + rgb->encoder.crtc_endpoint_id = endpoint_id; + ret = drm_connector_attach_encoder(connector, encoder); if (ret < 0) { DRM_DEV_ERROR(drm_dev->dev, @@ -182,6 +182,6 @@ void rockchip_rgb_fini(struct rockchip_rgb *rgb) { drm_panel_bridge_remove(rgb->bridge); drm_connector_cleanup(>connector); - drm_encoder_cleanup(>encoder); + drm_encoder_cleanup(>encoder.encoder); } EXPORT_SYMBOL_GPL(rockchip_rgb_fini); -- 2.30.2
[PATCH v3 1/6] drm/rockchip: vop2: initialize possible_crtcs properly
The variable possible_crtcs is only initialized for primary and overlay planes. Since the VOP2 driver only supports these plane types at the moment, the current code is safe. However, in order to provide a future-proof solution, fix the initialization of the variable. Reported-by: kernel test robot Reported-by: Dan Carpenter Signed-off-by: Michael Riesch --- v3: - no changes v2: - new patch drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index 8cecf81a5ae0..374ef821b453 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -2322,10 +2322,11 @@ static int vop2_create_crtc(struct vop2 *vop2) /* change the unused primary window to overlay window */ win->type = DRM_PLANE_TYPE_OVERLAY; } - } - - if (win->type == DRM_PLANE_TYPE_OVERLAY) + } else if (win->type == DRM_PLANE_TYPE_OVERLAY) { possible_crtcs = (1 << nvps) - 1; + } else { + possible_crtcs = 0; + } ret = vop2_plane_init(vop2, win, possible_crtcs); if (ret) { -- 2.30.2
[PATCH v3 0/6] drm/rockchip: vop2: add support for the rgb output block
Hi all, This series adds support for the RGB output block that can be found in the Rockchip Video Output Processor (VOP) 2. Version 2 of this series incorporates the feedback by Dan Carpenter and Sascha Hauer. Version 3 fixes a dumb mistake pointed out by Sascha :-) Thanks for your comments! Patches 1-4 clean up the code and make it more general. Patch 5 activates the support for the RGB output block in the VOP2 driver. Patch 6 adds pinctrls for the 16-bit and 18-bit RGB data lines. Tested on a custom board featuring the RK3568 SoC with a 18-bit RGB display. Looking forward to your comments! Best regards, Michael Michael Riesch (6): drm/rockchip: vop2: initialize possible_crtcs properly drm/rockchip: rgb: embed drm_encoder into rockchip_encoder drm/rockchip: rgb: add video_port parameter to init function drm/rockchip: vop2: use symmetric function pair vop2_{create,destroy}_crtcs drm/rockchip: vop2: add support for the rgb output block arm64: dts: rockchip: add pinctrls for 16-bit/18-bit rgb interface to rk356x .../boot/dts/rockchip/rk3568-pinctrl.dtsi | 94 +++ drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 2 +- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 80 drivers/gpu/drm/rockchip/rockchip_rgb.c | 19 ++-- drivers/gpu/drm/rockchip/rockchip_rgb.h | 6 +- 5 files changed, 172 insertions(+), 29 deletions(-) base-commit: 1b929c02afd37871d5afb9d498426f83432e71c2 -- 2.30.2
[PATCH v6 2/6] drm/i915/pxp: add device link between i915 and mei_pxp
From: Alexander Usyskin Add device link with i915 as consumer and mei_pxp as supplier to ensure proper ordering of power flows. V2: condition on absence of heci_pxp to filter out DG Signed-off-by: Alexander Usyskin --- drivers/gpu/drm/i915/pxp/intel_pxp_tee.c | 11 +++ drivers/gpu/drm/i915/pxp/intel_pxp_types.h | 6 ++ 2 files changed, 17 insertions(+) diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c index 73aa8015f828..cd5b86216506 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c @@ -127,6 +127,12 @@ static int i915_pxp_tee_component_bind(struct device *i915_kdev, intel_wakeref_t wakeref; int ret = 0; + if (!HAS_HECI_PXP(i915)) { + pxp->component_dev_link = device_link_add(i915_kdev, tee_kdev, DL_FLAG_STATELESS); + if (drm_WARN_ON(>drm, !pxp->component_dev_link)) + return -ENODEV; + } + mutex_lock(>tee_mutex); pxp->pxp_component = data; pxp->pxp_component->tee_dev = tee_kdev; @@ -169,6 +175,11 @@ static void i915_pxp_tee_component_unbind(struct device *i915_kdev, mutex_lock(>tee_mutex); pxp->pxp_component = NULL; mutex_unlock(>tee_mutex); + + if (pxp->component_dev_link) { + device_link_remove(i915_kdev, tee_kdev); + pxp->component_dev_link = NULL; + } } static const struct component_ops i915_pxp_tee_component_ops = { diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h index 7dc5f08d1583..efd2f3915abe 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h @@ -32,6 +32,12 @@ struct intel_pxp { * which are protected by _mutex. */ struct i915_pxp_component *pxp_component; + + /** +* @component_dev_link: device link of the pxp-component enforcing i915 as the +* consumer. This is needed for legacy platform (TGL/ADL) full-feature usage. +*/ + struct device_link *component_dev_link; /** * @pxp_component_added: track if the pxp component has been added. * Set and cleared in tee init and fini functions respectively. -- 2.39.0
[PATCH v6 5/6] drm/i915/pxp: Trigger the global teardown for before suspending
A driver bug was recently discovered where the security firmware was receiving internal HW signals indicating that session key expirations had occurred. Architecturally, the firmware was expecting a response from the GuC to acknowledge the event with the firmware side. However the OS was in a suspended state and GuC had been reset. Internal specifications actually required the driver to ensure that all active sessions be properly cleaned up in such cases where the system is suspended and the GuC potentially unable to respond. This patch adds the global teardown code in i915's suspend_prepare code path. Signed-off-by: Alan Previn Reviewed-by: Juston Li --- drivers/gpu/drm/i915/pxp/intel_pxp.c | 65 +--- drivers/gpu/drm/i915/pxp/intel_pxp.h | 1 + drivers/gpu/drm/i915/pxp/intel_pxp_pm.c | 2 +- drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 6 +- drivers/gpu/drm/i915/pxp/intel_pxp_session.h | 5 ++ 5 files changed, 66 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c index cfc9af8b3d21..9d4c7724e98e 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c @@ -270,6 +270,60 @@ static bool pxp_component_bound(struct intel_pxp *pxp) return bound; } +static int __pxp_global_teardown_final(struct intel_pxp *pxp) +{ + if (!pxp->arb_is_valid) + return 0; + /* +* To ensure synchronous and coherent session teardown completion +* in response to suspend or shutdown triggers, don't use a worker. +*/ + intel_pxp_mark_termination_in_progress(pxp); + intel_pxp_terminate(pxp, false); + + if (!wait_for_completion_timeout(>termination, msecs_to_jiffies(250))) + return -ETIMEDOUT; + + return 0; +} + +static int __pxp_global_teardown_restart(struct intel_pxp *pxp) +{ + if (pxp->arb_is_valid) + return 0; + /* +* The arb-session is currently inactive and we are doing a reset and restart +* due to a runtime event. Use the worker that was designed for this. +*/ + pxp_queue_termination(pxp); + + if (!wait_for_completion_timeout(>termination, msecs_to_jiffies(250))) + return -ETIMEDOUT; + + return 0; +} + +void intel_pxp_end(struct intel_pxp *pxp) +{ + struct drm_i915_private *i915 = pxp->ctrl_gt->i915; + intel_wakeref_t wakeref; + + if (!intel_pxp_is_enabled(pxp)) + return; + + wakeref = intel_runtime_pm_get(>runtime_pm); + + mutex_lock(>arb_mutex); + + if (__pxp_global_teardown_final(pxp)) + drm_dbg(>drm, "PXP end timed out\n"); + + mutex_unlock(>arb_mutex); + + intel_pxp_fini_hw(pxp); + intel_runtime_pm_put(>runtime_pm, wakeref); +} + /* * the arb session is restarted from the irq work when we receive the * termination completion interrupt @@ -286,16 +340,9 @@ int intel_pxp_start(struct intel_pxp *pxp) mutex_lock(>arb_mutex); - if (pxp->arb_is_valid) - goto unlock; - - pxp_queue_termination(pxp); - - if (!wait_for_completion_timeout(>termination, - msecs_to_jiffies(250))) { - ret = -ETIMEDOUT; + ret = __pxp_global_teardown_restart(pxp); + if (ret) goto unlock; - } /* make sure the compiler doesn't optimize the double access */ barrier(); diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h index 9658d3005222..3ded0890cd27 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h @@ -27,6 +27,7 @@ void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp); void intel_pxp_tee_end_arb_fw_session(struct intel_pxp *pxp, u32 arb_session_id); int intel_pxp_start(struct intel_pxp *pxp); +void intel_pxp_end(struct intel_pxp *pxp); int intel_pxp_key_check(struct intel_pxp *pxp, struct drm_i915_gem_object *obj, diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c index 892d39cc61c1..e427464aa131 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c @@ -16,7 +16,7 @@ void intel_pxp_suspend_prepare(struct intel_pxp *pxp) if (!intel_pxp_is_enabled(pxp)) return; - pxp->arb_is_valid = false; + intel_pxp_end(pxp); intel_pxp_invalidate(pxp); } diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c index 74ed7e16e481..448cacb0465d 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c @@ -115,11 +115,11 @@ static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp) return ret; } -static void pxp_terminate(struct
[PATCH v6 1/6] mei: mei-me: resume device in prepare
From: Alexander Usyskin Asynchronous runtime resume is not possible while the system is suspending. The power management subsystem resumes the device only in the suspend phase, not in the prepare phase. Force resume device in prepare to allow drivers on mei bus to communicate in their prepare callbacks. Signed-off-by: Alexander Usyskin Reviewed-by: Tomas Winkler --- drivers/misc/mei/pci-me.c | 20 +++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index 5bf0d50d55a0..676d566f38dd 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c @@ -342,6 +342,12 @@ static void mei_me_remove(struct pci_dev *pdev) } #ifdef CONFIG_PM_SLEEP +static int mei_me_pci_prepare(struct device *device) +{ + pm_runtime_resume(device); + return 0; +} + static int mei_me_pci_suspend(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); @@ -398,7 +404,17 @@ static int mei_me_pci_resume(struct device *device) return 0; } -#endif /* CONFIG_PM_SLEEP */ + +static void mei_me_pci_complete(struct device *device) +{ + pm_runtime_suspend(device); +} +#else /* CONFIG_PM_SLEEP */ + +#define mei_me_pci_prepare NULL +#define mei_me_pci_complete NULL + +#endif /* !CONFIG_PM_SLEEP */ #ifdef CONFIG_PM static int mei_me_pm_runtime_idle(struct device *device) @@ -501,6 +517,8 @@ static inline void mei_me_unset_pm_domain(struct mei_device *dev) } static const struct dev_pm_ops mei_me_pm_ops = { + .prepare = mei_me_pci_prepare, + .complete = mei_me_pci_complete, SET_SYSTEM_SLEEP_PM_OPS(mei_me_pci_suspend, mei_me_pci_resume) SET_RUNTIME_PM_OPS( -- 2.39.0
[PATCH v6 3/6] mei: clean pending read with vtag on bus
From: Alexander Usyskin Client on bus have only one vtag map slot and should disregard the vtag value when cleaning pending read flag. Fixes read flow control message unexpectedly generated when clent on bus send messages with different vtags. Signed-off-by: Alexander Usyskin Reviewed-by: Tomas Winkler --- drivers/misc/mei/client.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 9ddb854b8155..5c19097266fe 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -1343,7 +1343,9 @@ static void mei_cl_reset_read_by_vtag(const struct mei_cl *cl, u8 vtag) struct mei_cl_vtag *vtag_l; list_for_each_entry(vtag_l, >vtag_map, list) { - if (vtag_l->vtag == vtag) { + /* The client on bus has one fixed vtag map */ + if ((cl->cldev && mei_cldev_enabled(cl->cldev)) || + vtag_l->vtag == vtag) { vtag_l->pending_read = false; break; } -- 2.39.0
[PATCH v6 4/6] drm/i915/pxp: Invalidate all PXP fw sessions during teardown
A gap was recently discovered where if an application did not invalidate all of the stream keys (intentionally or not), and the driver did a full PXP global teardown on the GT subsystem, we find that future session creation would fail on the security firmware's side of the equation. i915 is the entity that needs ensure the sessions' state across both iGT and security firmware are at a known clean point when performing a full global teardown. Architecturally speaking, i915 should inspect all active sessions and submit the invalidate-stream-key PXP command to the security firmware for each of them. However, for the upstream i915 driver we only support the arbitration session that can be created so that will be the only session we will cleanup. Signed-off-by: Alan Previn Reviewed-by: Juston Li Acked-by: Rodrigo Vivi --- drivers/gpu/drm/i915/pxp/intel_pxp.h | 1 + .../drm/i915/pxp/intel_pxp_cmd_interface_42.h | 15 .../i915/pxp/intel_pxp_cmd_interface_cmn.h| 3 ++ drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 2 ++ drivers/gpu/drm/i915/pxp/intel_pxp_tee.c | 35 +++ 5 files changed, 56 insertions(+) diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h index 04440fada711..9658d3005222 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h @@ -24,6 +24,7 @@ void intel_pxp_init_hw(struct intel_pxp *pxp); void intel_pxp_fini_hw(struct intel_pxp *pxp); void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp); +void intel_pxp_tee_end_arb_fw_session(struct intel_pxp *pxp, u32 arb_session_id); int intel_pxp_start(struct intel_pxp *pxp); diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_42.h b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_42.h index 739f9072fa5f..26f7d9f01bf3 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_42.h +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_42.h @@ -12,6 +12,9 @@ /* PXP-Opcode for Init Session */ #define PXP42_CMDID_INIT_SESSION 0x1e +/* PXP-Opcode for Invalidate Stream Key */ +#define PXP42_CMDID_INVALIDATE_STREAM_KEY 0x0007 + /* PXP-Input-Packet: Init Session (Arb-Session) */ struct pxp42_create_arb_in { struct pxp_cmd_header header; @@ -25,4 +28,16 @@ struct pxp42_create_arb_out { struct pxp_cmd_header header; } __packed; +/* PXP-Input-Packet: Invalidate Stream Key */ +struct pxp42_inv_stream_key_in { + struct pxp_cmd_header header; + u32 rsvd[3]; +} __packed; + +/* PXP-Output-Packet: Invalidate Stream Key */ +struct pxp42_inv_stream_key_out { + struct pxp_cmd_header header; + u32 rsvd; +} __packed; + #endif /* __INTEL_PXP_FW_INTERFACE_42_H__ */ diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h index aaa8187a0afb..ae9b151b7cb7 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h @@ -28,6 +28,9 @@ struct pxp_cmd_header { union { u32 status; /* out */ u32 stream_id; /* in */ +#define PXP_CMDHDR_EXTDATA_SESSION_VALID GENMASK(0, 0) +#define PXP_CMDHDR_EXTDATA_APP_TYPE GENMASK(1, 1) +#define PXP_CMDHDR_EXTDATA_SESSION_ID GENMASK(17, 2) }; /* Length of the message (excluding the header) */ u32 buffer_len; diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c index ae413580b81a..74ed7e16e481 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c @@ -110,6 +110,8 @@ static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp) intel_uncore_write(gt->uncore, PXP_GLOBAL_TERMINATE, 1); + intel_pxp_tee_end_arb_fw_session(pxp, ARB_SESSION); + return ret; } diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c index cd5b86216506..aa0ad46e524b 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c @@ -319,3 +319,38 @@ int intel_pxp_tee_cmd_create_arb_session(struct intel_pxp *pxp, return ret; } + +void intel_pxp_tee_end_arb_fw_session(struct intel_pxp *pxp, u32 session_id) +{ + struct drm_i915_private *i915 = pxp->ctrl_gt->i915; + struct pxp42_inv_stream_key_in msg_in = {0}; + struct pxp42_inv_stream_key_out msg_out = {0}; + int ret, trials = 0; + +try_again: + memset(_in, 0, sizeof(msg_in)); + memset(_out, 0, sizeof(msg_out)); + msg_in.header.api_version = PXP_APIVER(4, 2); + msg_in.header.command_id = PXP42_CMDID_INVALIDATE_STREAM_KEY; + msg_in.header.buffer_len = sizeof(msg_in) - sizeof(msg_in.header); + + msg_in.header.stream_id = FIELD_PREP(PXP_CMDHDR_EXTDATA_SESSION_VALID, 1); + msg_in.header.stream_id |=
[PATCH v6 6/6] drm/i915/pxp: Pxp hw init should be in resume_complete
During suspend flow, i915 currently achors' on the pm_suspend_prepare callback as the location where we quiesce the entire GPU and perform all necessary cleanup in order to go into suspend. PXP is also called during this time to perform the arbitration session teardown (with the assurance no additional GEM IOCTLs will come after that could restart the session). However, if other devices or drivers fail their suspend_prepare, the system will not go into suspend and i915 will be expected to resume operation. In this case, we need to re-initialize the PXP hardware and this really should be done within the pm_resume_complete callback which is the correct opposing function in the resume sequence to match pm_suspend_prepare of the suspend sequence. Because this callback is the last thing at the end of resuming we expect little to no impact to the rest of the i915 resume sequence with this change. Signed-off-by: Alan Previn Reviewed-by: Daniele Ceraolo Spurio Acked-by: Rodrigo Vivi --- drivers/gpu/drm/i915/i915_driver.c | 20 ++-- drivers/gpu/drm/i915/pxp/intel_pxp_pm.c | 2 +- drivers/gpu/drm/i915/pxp/intel_pxp_pm.h | 6 +++--- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 6469c7c1e154..122736b48938 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -1167,6 +1167,13 @@ static bool suspend_to_idle(struct drm_i915_private *dev_priv) return false; } +static void i915_drm_complete(struct drm_device *dev) +{ + struct drm_i915_private *i915 = to_i915(dev); + + intel_pxp_resume_complete(i915->pxp); +} + static int i915_drm_prepare(struct drm_device *dev) { struct drm_i915_private *i915 = to_i915(dev); @@ -1367,8 +1374,6 @@ static int i915_drm_resume(struct drm_device *dev) i915_gem_resume(dev_priv); - intel_pxp_resume(dev_priv->pxp); - intel_modeset_init_hw(dev_priv); intel_init_clock_gating(dev_priv); intel_hpd_init(dev_priv); @@ -1560,6 +1565,16 @@ static int i915_pm_resume(struct device *kdev) return i915_drm_resume(>drm); } +static void i915_pm_complete(struct device *kdev) +{ + struct drm_i915_private *i915 = kdev_to_i915(kdev); + + if (i915->drm.switch_power_state == DRM_SWITCH_POWER_OFF) + return; + + i915_drm_complete(>drm); +} + /* freeze: before creating the hibernation_image */ static int i915_pm_freeze(struct device *kdev) { @@ -1780,6 +1795,7 @@ const struct dev_pm_ops i915_pm_ops = { .suspend_late = i915_pm_suspend_late, .resume_early = i915_pm_resume_early, .resume = i915_pm_resume, + .complete = i915_pm_complete, /* * S4 event handlers diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c index e427464aa131..4f836b317424 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c @@ -34,7 +34,7 @@ void intel_pxp_suspend(struct intel_pxp *pxp) } } -void intel_pxp_resume(struct intel_pxp *pxp) +void intel_pxp_resume_complete(struct intel_pxp *pxp) { if (!intel_pxp_is_enabled(pxp)) return; diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h index 586be769104f..06b46f535b42 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h @@ -11,7 +11,7 @@ struct intel_pxp; #ifdef CONFIG_DRM_I915_PXP void intel_pxp_suspend_prepare(struct intel_pxp *pxp); void intel_pxp_suspend(struct intel_pxp *pxp); -void intel_pxp_resume(struct intel_pxp *pxp); +void intel_pxp_resume_complete(struct intel_pxp *pxp); void intel_pxp_runtime_suspend(struct intel_pxp *pxp); #else static inline void intel_pxp_suspend_prepare(struct intel_pxp *pxp) @@ -22,7 +22,7 @@ static inline void intel_pxp_suspend(struct intel_pxp *pxp) { } -static inline void intel_pxp_resume(struct intel_pxp *pxp) +static inline void intel_pxp_resume_complete(struct intel_pxp *pxp) { } @@ -32,6 +32,6 @@ static inline void intel_pxp_runtime_suspend(struct intel_pxp *pxp) #endif static inline void intel_pxp_runtime_resume(struct intel_pxp *pxp) { - intel_pxp_resume(pxp); + intel_pxp_resume_complete(pxp); } #endif /* __INTEL_PXP_PM_H__ */ -- 2.39.0
[PATCH v6 0/6] drm/i915/pxp: Add missing cleanup steps for PXP global-teardown
A customer issue was recently discovered and in the process a gap in i915's PXP interaction with HW+FW architecure was also realized. This series adds those missing pieces. This fix includes changes where i915 calls into the mei component interface in order to submit requests to the security firmware during the i915's suspend_prepare flow. This change did expose a blocking issue in the mei component side that was discovered while testing in rev1. The issue being the mei-pxp component driver not being able to runtime-resume while being within the suspend_prepare callstack. Thus, we have now included the mei patches (from Alexander) that fixes that issue by adding a device-link based on the interface type to ensure mei side runtime resume during the i915's suspend_prepare call. That said, as per request from Alexander, we seek Greg's and Tomas' review for the mei patches (Patch 1, 2 and 3). Patch 2, although is a change in the i915 code, is the mei component device link change. The individual patches explain more details. Patch 7 can be ignored as it won't be merged and is only meant to ensure the CI run's the PXP subtests with PXP support enabled in KConfig. Changes from prior revs: v1: - Dont need to teardown non-arbitration sessions (Juston). - Fix builds when PXP is enabled in config (Alan/CI-build). - Fix the broken pm-suspend-resume symmetry when we do this pxp-session-teardown during i915s pm_suspend_prepare by ensuring the init is done during i915s pm_resume_complete. v2: - Rebase on latest drm-tip after PXP subsytem was promoted to global. - Remove "INTEL_PXP_MAX_HWDRM_SESSIONS" unneeded (Juston Li). - Added mei patches that are dependencies for this series to successfully pass testing when PXP config is enabled. v3: - Added fix for mei patch when CONFIG_PM_SLEEP is off (reported by kernel test robot ). v4: - Added "DRM_SWITCH_POWER_OFF" check and removed bail-out if '!i915' that wont happen in i915_pm_complete (Daniele). - move i915_pm_complete to appear in i915_pm_resume. - One more fix for mei patch when CONFIG_PM_SLEEP is off (reported by kernel test robot ). v5: - Reworked Patch#2 on device link establishment. Don't hide triggering device-link behind drm_WARN, return -ENODEV if it fails and stash the returned device_link struct. Alan Previn (3): drm/i915/pxp: Invalidate all PXP fw sessions during teardown drm/i915/pxp: Trigger the global teardown for before suspending drm/i915/pxp: Pxp hw init should be in resume_complete Alexander Usyskin (3): mei: mei-me: resume device in prepare drm/i915/pxp: add device link between i915 and mei_pxp mei: clean pending read with vtag on bus drivers/gpu/drm/i915/i915_driver.c| 20 +- drivers/gpu/drm/i915/pxp/intel_pxp.c | 65 --- drivers/gpu/drm/i915/pxp/intel_pxp.h | 2 + .../drm/i915/pxp/intel_pxp_cmd_interface_42.h | 15 + .../i915/pxp/intel_pxp_cmd_interface_cmn.h| 3 + drivers/gpu/drm/i915/pxp/intel_pxp_pm.c | 4 +- drivers/gpu/drm/i915/pxp/intel_pxp_pm.h | 6 +- drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 8 ++- drivers/gpu/drm/i915/pxp/intel_pxp_session.h | 5 ++ drivers/gpu/drm/i915/pxp/intel_pxp_tee.c | 46 + drivers/gpu/drm/i915/pxp/intel_pxp_types.h| 6 ++ drivers/misc/mei/client.c | 4 +- drivers/misc/mei/pci-me.c | 20 +- 13 files changed, 183 insertions(+), 21 deletions(-) base-commit: 6a023df4443d313724dc96d1fff15193bb7ec5b8 -- 2.39.0
Re: DMA-heap driver hints
On Mon, Jan 23, 2023 at 8:29 AM Christian König wrote: > Am 23.01.23 um 14:55 schrieb Laurent Pinchart: > > - I assume some drivers will be able to support multiple heaps. How do > >you envision this being implemented ? > > I don't really see an use case for this. > > We do have some drivers which say: for this use case you can use > whatever you want, but for that use case you need to use specific memory > (scan out on GPUs for example works like this). > [snipping the constraints argument, which I agree with] > > What we do have is compatibility between heaps. E.g. a CMA heap is > usually compatible with the system heap or might even be a subset of > another CMA heap. But I wanted to add that as next step to the heaps > framework itself. So the difficult question is how is userland supposed to know which heap is compatible with which? If you have two devices, one that points to heap "foo" and the other points to heap "bar", how does userland know that "foo" satisfies the constraints of "bar" but "bar" doesn't satisfy the constraints of "foo". (foo ="cma", bar="system") I think it would be much better for device 1 to list "foo" and device 2 to list "foo" and "bar", so you can find that "foo" is the common heap which will solve both devices' needs. > > - Devices could have different constraints based on particular > >configurations. For instance, a device may require specific memory > >layout for multi-planar YUV formats only (as in allocating the Y and C > >planes of NV12 from different memory banks). A dynamic API may thus be > >needed (but may also be very painful to use from userspace). > > Uff, good to know. But I'm not sure how to expose stuff like that. Yeah. These edge cases are really hard to solve generically. And single devices that have separate constraints for different uses are also not going to be solvable with a simple linking approach. But I do wonder if a generic solution to all cases is needed (especially if it really isn't possible)? If we leave the option for gralloc like omniscient device-specific userland policy, those edge cases can be handled by those devices that can't run generic logic. And those devices just won't be able to be supported by generic distros, hopefully motivating future designs to have less odd constraints? thanks -john
Re: DMA-heap driver hints
On Mon, Jan 23, 2023 at 5:55 AM Laurent Pinchart wrote: > > Hi Christian, > > CC'ing James as I think this is related to his work on the unix device > memory allocator ([1]). > > [1] > https://lore.kernel.org/dri-devel/8b555674-1c5b-c791-4547-2ea7c16ae...@nvidia.com/ > > On Mon, Jan 23, 2023 at 01:37:54PM +0100, Christian König wrote: > > Hi guys, > > > > this is just an RFC! The last time we discussed the DMA-buf coherency > > problem [1] we concluded that DMA-heap first needs a better way to > > communicate to userspace which heap to use for a certain device. > > > > As far as I know userspace currently just hard codes that information > > which is certainly not desirable considering that we should have this > > inside the kernel as well. > > > > So what those two patches here do is to first add some > > dma_heap_create_device_link() and dma_heap_remove_device_link() > > function and then demonstrating the functionality with uvcvideo > > driver. > > > > The preferred DMA-heap is represented with a symlink in sysfs between > > the device and the virtual DMA-heap device node. > > I'll start with a few high-level comments/questions: > > - Instead of tying drivers to heaps, have you considered a system where > a driver would expose constraints, and a heap would then be selected > based on those constraints ? A tight coupling between heaps and > drivers means downstream patches to drivers in order to use > vendor-specific heaps, that sounds painful. Though, maybe it should be in that case. More motivation to get your heap (and its users) upstream. :) > A constraint-based system would also, I think, be easier to extend > with additional constraints in the future. I think the issue of enumerating and exposing constraints to userland is just really tough. While on any one system there is a fixed number of constraints, it's not clear we could come up with a bounded set for all systems. To avoid this back in the ION days I had proposed an idea of userland having devices share an opaque constraint cookie, which userland could mask together between devices and then find a heap that matches the combined cookie, which would avoid exposing specific constraints to userland, but the processes of using it seemed like such a mess to explain. So I think this driver driven links approach is pretty reasonable. I do worry we might get situations where the drivers ability to use a heap depends on some other factor (dts iommu setup maybe?), which the driver might not know on its own, but I think having the driver special-case that to resolve it would be doable. > - I assume some drivers will be able to support multiple heaps. How do > you envision this being implemented ? Yeah. I also agree we need to have multiple heap links. > - Devices could have different constraints based on particular > configurations. For instance, a device may require specific memory > layout for multi-planar YUV formats only (as in allocating the Y and C > planes of NV12 from different memory banks). A dynamic API may thus be > needed (but may also be very painful to use from userspace). Yeah. While I know folks really don't like the static userspace config model that Android uses, I do fret that once we get past what a workable heap is, it still won't address what the ideal heap is. For instance, we might find that the system heap works for a given pipeline, but because the cpu doesn't use the buffer in one case, the system-uncached heap is really the best choice for performance. But in another pipeline with the same devices, if the cpu is reading and writing the buffer quite a bit, one would want the standard system heap. Because userland is the only one who can know the path a buffer will take, userland is really the best place to choose the ideal allocation type. So while I don't object to this link based approach just to allow a generic userland to find a working buffer type for a given set of devices, I don't think it will be able to replace having device specific userland policy (like gralloc), though it's my personal hope the policy can be formalized to a config file rather then having device specific binaries. thanks -john
Re: [PATCH 1/2] dma-heap: add device link and unlink functions
On Mon, Jan 23, 2023 at 4:38 AM Christian König wrote: > > This allows device drivers to specify a DMA-heap where they want their > buffers to be allocated from. This information is then exposed as > sysfs link between the device and the DMA-heap. > > Useful for userspace when in need to decide from which provider to > allocate a buffer. > > Signed-off-by: Christian König Hey Christian! Thanks so much for sending this out and also thanks for including me (Adding TJ as well)! This looks like a really interesting approach, but I have a few thoughts below. > --- > drivers/dma-buf/dma-heap.c | 41 ++ > include/linux/dma-heap.h | 35 > 2 files changed, 68 insertions(+), 8 deletions(-) > > diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c > index c9e41e8a9e27..0f7cf713c22f 100644 > --- a/drivers/dma-buf/dma-heap.c > +++ b/drivers/dma-buf/dma-heap.c > @@ -31,6 +31,7 @@ > * @heap_devt heap device node > * @list list head connecting to list of heaps > * @heap_cdev heap char device > + * @dev: heap device in sysfs > * > * Represents a heap of memory from which buffers can be made. > */ > @@ -41,6 +42,7 @@ struct dma_heap { > dev_t heap_devt; > struct list_head list; > struct cdev heap_cdev; > + struct device *dev; > }; > > static LIST_HEAD(heap_list); > @@ -49,6 +51,33 @@ static dev_t dma_heap_devt; > static struct class *dma_heap_class; > static DEFINE_XARRAY_ALLOC(dma_heap_minors); > > +int dma_heap_create_device_link(struct device *dev, const char *heap) > +{ > + struct dma_heap *h; > + > + /* check the name is valid */ > + mutex_lock(_list_lock); > + list_for_each_entry(h, _list, list) { > + if (!strcmp(h->name, heap)) > + break; > + } > + mutex_unlock(_list_lock); > + > + if (list_entry_is_head(h, _list, list)) { > + pr_err("dma_heap: Link to invalid heap requested %s\n", heap); > + return -EINVAL; > + } > + > + return sysfs_create_link(>kobj, >dev->kobj, DEVNAME); > +} So, one concern with this (if I'm reading this right) is it seems like a single heap link may be insufficient. There may be multiple heaps that a driver could work with (especially if the device isn't very constrained), so when sharing a buffer with a second device that is more constrained we'd have the same problem we have now where userspace just needs to know which device is the more constrained one to allocate for. So it might be useful to have a sysfs "dma_heaps" directory with the supported heaps linked from there? That way userland could find across the various devices the heap-link that was common. This still has the downside that every driver needs to be aware of every heap, and when new heaps are added, it may take awhile before folks might be able to assess if a device is compatible or not to update it, so I suspect we'll have eventually some loose constraint-based helpers to register links. But I think this at least moves us in a workable direction, so again, I'm really glad to see you send this out! thanks -john
Re: DMA-heap driver hints
On 1/23/23 08:58, Laurent Pinchart wrote: Hi Christian, On Mon, Jan 23, 2023 at 05:29:18PM +0100, Christian König wrote: Am 23.01.23 um 14:55 schrieb Laurent Pinchart: Hi Christian, CC'ing James as I think this is related to his work on the unix device memory allocator ([1]). Thank you for including me. [1] https://lore.kernel.org/dri-devel/8b555674-1c5b-c791-4547-2ea7c16ae...@nvidia.com/ On Mon, Jan 23, 2023 at 01:37:54PM +0100, Christian König wrote: Hi guys, this is just an RFC! The last time we discussed the DMA-buf coherency problem [1] we concluded that DMA-heap first needs a better way to communicate to userspace which heap to use for a certain device. As far as I know userspace currently just hard codes that information which is certainly not desirable considering that we should have this inside the kernel as well. So what those two patches here do is to first add some dma_heap_create_device_link() and dma_heap_remove_device_link() function and then demonstrating the functionality with uvcvideo driver. The preferred DMA-heap is represented with a symlink in sysfs between the device and the virtual DMA-heap device node. I'll start with a few high-level comments/questions: - Instead of tying drivers to heaps, have you considered a system where a driver would expose constraints, and a heap would then be selected based on those constraints ? A tight coupling between heaps and drivers means downstream patches to drivers in order to use vendor-specific heaps, that sounds painful. I was wondering the same thing as well, but came to the conclusion that just the other way around is the less painful approach. From a kernel point of view, sure, it's simpler and thus less painful. From the point of view of solving the whole issue, I'm not sure :-) The problem is that there are so many driver specific constrains that I don't even know where to start from. That's where I was hoping James would have some feedback for us, based on the work he did on the Unix device memory allocator. If that's not the case, we can brainstorm this from scratch. Simon Ser's and my presentation from XDC 2020 focused entirely on this. The idea was not to try to enumerate every constraint up front, but rather to develop an extensible mechanism that would be flexible enough to encapsulate many disparate types of constraints and perform set operations on them (merging sets was the only operation we tried to solve). Simon implemented a prototype header-only library to implement the mechanism: https://gitlab.freedesktop.org/emersion/drm-constraints The links to the presentation and talk are below, along with notes from the follow-up workshop. https://lpc.events/event/9/contributions/615/attachments/704/1301/XDC_2020__Allocation_Constraints.pdf https://www.youtube.com/watch?v=HZEClOP5TIk https://paste.sr.ht/~emersion/c43b30be08bab1882f1b107402074462bba3b64a Note one of the hard parts of this was figuring out how to express a device or heap within the constraint structs. One of the better ideas proposed back then was something like heap IDs, where dma heaps would each have one, and devices could register their own heaps (or even just themselves?) with the heap subsystem and be assigned a locally-unique ID that userspace could pass around. This sounds similar to what you're proposing. Perhaps a reasonable identifier is a device (major, minor) pair. Such a constraint could be expressed as a symlink for easy visualization/discoverability from userspace, but might be easier to serialize over the wire as the (major, minor) pair. I'm not clear which direction is better to express this either: As a link from heap->device, or device->heap. A constraint-based system would also, I think, be easier to extend with additional constraints in the future. - I assume some drivers will be able to support multiple heaps. How do you envision this being implemented ? I don't really see an use case for this. One use case I know of here is same-vendor GPU local memory on different GPUs. NVIDIA GPUs have certain things they can only do on local memory, certain things they can do on all memory, and certain things they can only do on memory local to another NVIDIA GPU, especially when there exists an NVLink interface between the two. So they'd ideally express different constraints for heap representing each of those. The same thing is often true of memory on remote devices that are at various points in a PCIe topology. We've had situations where we could only get enough bandwidth between two PCIe devices when they were less than some number of hops away on the PCI tree. We hard-coded logic to detect that in our userspace drivers, but we could instead expose it as a constraint on heaps that would express which devices can accomplish certain operations as pairs. Similarly to the last one, I would assume (But haven't yet run into in my personal experience)
Re: [PATCH 2/2] media: uvcvideo: expose dma-heap hint to userspace
Hi Christian, I love your patch! Perhaps something to improve: [auto build test WARNING on drm-misc/drm-misc-next] [also build test WARNING on media-tree/master drm-tip/drm-tip linus/master v6.2-rc5] [cannot apply to next-20230123] [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#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Christian-K-nig/media-uvcvideo-expose-dma-heap-hint-to-userspace/20230123-213836 base: git://anongit.freedesktop.org/drm/drm-misc drm-misc-next patch link: https://lore.kernel.org/r/20230123123756.401692-3-christian.koenig%40amd.com patch subject: [PATCH 2/2] media: uvcvideo: expose dma-heap hint to userspace config: i386-randconfig-a002-20230123 (https://download.01.org/0day-ci/archive/20230124/202301241137.qt2rnq5t-...@intel.com/config) compiler: gcc-11 (Debian 11.3.0-8) 11.3.0 reproduce (this is a W=1 build): # https://github.com/intel-lab-lkp/linux/commit/adc04dccd892eec7f84c6ec112b48df376172e48 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Christian-K-nig/media-uvcvideo-expose-dma-heap-hint-to-userspace/20230123-213836 git checkout adc04dccd892eec7f84c6ec112b48df376172e48 # save the config file mkdir build_dir && cp config build_dir/.config make W=1 O=build_dir ARCH=i386 olddefconfig make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash drivers/media/usb/uvc/ If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot All warnings (new ones prefixed by >>): In file included from drivers/media/usb/uvc/uvc_driver.c:10: >> include/linux/dma-heap.h:92:5: warning: no previous prototype for >> 'dma_heap_create_device_link' [-Wmissing-prototypes] 92 | int dma_heap_create_device_link(struct device *dev, const char *heap) | ^~~ >> include/linux/dma-heap.h:97:6: warning: no previous prototype for >> 'dma_heap_remove_device_link' [-Wmissing-prototypes] 97 | void dma_heap_remove_device_link(struct device *dev) | ^~~ vim +/dma_heap_create_device_link +92 include/linux/dma-heap.h 4ce5c5c0cf31f4 Christian König 2023-01-23 91 4ce5c5c0cf31f4 Christian König 2023-01-23 @92 int dma_heap_create_device_link(struct device *dev, const char *heap) 4ce5c5c0cf31f4 Christian König 2023-01-23 93 { 4ce5c5c0cf31f4 Christian König 2023-01-23 94 return 0; 4ce5c5c0cf31f4 Christian König 2023-01-23 95 } 4ce5c5c0cf31f4 Christian König 2023-01-23 96 4ce5c5c0cf31f4 Christian König 2023-01-23 @97 void dma_heap_remove_device_link(struct device *dev) 4ce5c5c0cf31f4 Christian König 2023-01-23 98 { 4ce5c5c0cf31f4 Christian König 2023-01-23 99 } 4ce5c5c0cf31f4 Christian König 2023-01-23 100 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests
Re: [Intel-gfx] [PATCH v5 2/6] drm/i915/pxp: add device link between i915 and mei_pxp
On Mon, 2023-01-23 at 09:31 -0500, Vivi, Rodrigo wrote: > On Sun, Jan 22, 2023 at 06:57:24AM +, Usyskin, Alexander wrote: > > > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c > > > b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c > > > > index d50354bfb993..bef6d7f8ac55 100644 > > > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c > > > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c > > > > @@ -127,6 +127,10 @@ static int i915_pxp_tee_component_bind(struct > > > alan:snip. Thanks Jani, Rodrigo and Alex. I'll re-rev with all of Rodrigo's recommendation: - will break down the initial code so we dont hide device-link behind drm_WARN_ON - since i didnt hear any hard objection - I will stick with Rodrigo's recommendation to stash the device-link. - dont need DL_FLAG_PM_RUNTIME - use -ENODEV probably like this: if (!HAS_HECI_PXP(i915)) { pxp->component_dev_link = device_link_add(i915_kdev, tee_kdev, DL_FLAG_STATELESS); if (drm_WARN_ON(>drm, !pxp->component_dev_link)) return -ENODEV; } alan:snip.
Re: [Freedreno] [PATCH] drm/msm/dpu: sc7180: add missing WB2 clock control
On 1/16/2023 2:30 AM, Dmitry Baryshkov wrote: Add missing DPU_CLK_CTRL_WB2 to sc7180_mdp clocks array. Fixes: 51e4d60e6ba5 ("drm/msm/dpu: add writeback support for sc7180") Signed-off-by: Dmitry Baryshkov Tested-by: Jessica Zhang # Trogdor (sc7180) --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 504a22c76412..c7103b0445b6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -546,6 +546,8 @@ static const struct dpu_mdp_cfg sc7180_mdp[] = { .reg_off = 0x2B4, .bit_off = 8}, .clk_ctrls[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2C4, .bit_off = 8}, + .clk_ctrls[DPU_CLK_CTRL_WB2] = { + .reg_off = 0x3B8, .bit_off = 24}, }, }; -- 2.39.0
Re: [PATCH v2 1/3] drm/msm/mdss: convert UBWC setup to use match data
On 1/19/2023 9:26 PM, Dmitry Baryshkov wrote: On Fri, 20 Jan 2023 at 00:54, Abhinav Kumar wrote: On 1/17/2023 5:04 PM, Dmitry Baryshkov wrote: To simplify adding new platforms and to make settings more obvious, rewrite the UBWC setup to use the data structure to pass platform config rather than just calling the functions direcly. Signed-off-by: Dmitry Baryshkov I was reviewing this series and https://patchwork.freedesktop.org/series/111732/ together. More I think about it, it seems like we are duplicating the same values here and in the catalog. Yes, these two are different drivers. But now that you are adding the UBWC entries here using the compatible string so you are creating something like a "catalog" here. In that case, why dont we remove the entries from dpu catalog and in the DPU driver get the parent's match data as we know that the msm_mdss is the parent of DPU driver I should give it a thought, especially since we are trying to clean up the DPU catalog. I just went through the cover letter of https://patchwork.freedesktop.org/patch/519752/ and it mentions "My itent is to land both series and then to make DPU request this data from the MDSS driver" This means that the parent data suggestion will be implemented? Let me know your thoughts. --- drivers/gpu/drm/msm/msm_mdss.c | 181 +++-- 1 file changed, 105 insertions(+), 76 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c index 02646e4bb4cd..799672b88716 100644 --- a/drivers/gpu/drm/msm/msm_mdss.c +++ b/drivers/gpu/drm/msm/msm_mdss.c @@ -16,9 +16,6 @@ #include "msm_drv.h" #include "msm_kms.h" -/* for DPU_HW_* defines */ -#include "disp/dpu1/dpu_hw_catalog.h" - #define HW_REV 0x0 #define HW_INTR_STATUS 0x0010 @@ -29,6 +26,16 @@ #define MIN_IB_BW 4UL /* Min ib vote 400MB */ +struct msm_mdss_data { + u32 ubwc_version; + /* can be read from register 0x58 */ + u32 ubwc_dec_version; + u32 ubwc_swizzle; + u32 ubwc_static; + u32 highest_bank_bit; + u32 macrotile_mode; +}; + struct msm_mdss { struct device *dev; @@ -40,6 +47,7 @@ struct msm_mdss { unsigned long enabled_mask; struct irq_domain *domain; } irq_controller; + const struct msm_mdss_data *mdss_data; struct icc_path *path[2]; u32 num_paths; }; @@ -182,46 +190,40 @@ static int _msm_mdss_irq_domain_add(struct msm_mdss *msm_mdss) #define UBWC_3_0 0x3000 #define UBWC_4_0 0x4000 -static void msm_mdss_setup_ubwc_dec_20(struct msm_mdss *msm_mdss, -u32 ubwc_static) +static void msm_mdss_setup_ubwc_dec_20(struct msm_mdss *msm_mdss) { - writel_relaxed(ubwc_static, msm_mdss->mmio + UBWC_STATIC); + const struct msm_mdss_data *data = msm_mdss->mdss_data; + + writel_relaxed(data->ubwc_static, msm_mdss->mmio + UBWC_STATIC); } -static void msm_mdss_setup_ubwc_dec_30(struct msm_mdss *msm_mdss, -unsigned int ubwc_version, -u32 ubwc_swizzle, -u32 highest_bank_bit, -u32 macrotile_mode) +static void msm_mdss_setup_ubwc_dec_30(struct msm_mdss *msm_mdss) { - u32 value = (ubwc_swizzle & 0x1) | - (highest_bank_bit & 0x3) << 4 | - (macrotile_mode & 0x1) << 12; + const struct msm_mdss_data *data = msm_mdss->mdss_data; + u32 value = (data->ubwc_swizzle & 0x1) | + (data->highest_bank_bit & 0x3) << 4 | + (data->macrotile_mode & 0x1) << 12; - if (ubwc_version == UBWC_3_0) + if (data->ubwc_version == UBWC_3_0) value |= BIT(10); - if (ubwc_version == UBWC_1_0) + if (data->ubwc_version == UBWC_1_0) value |= BIT(8); writel_relaxed(value, msm_mdss->mmio + UBWC_STATIC); } -static void msm_mdss_setup_ubwc_dec_40(struct msm_mdss *msm_mdss, -unsigned int ubwc_version, -u32 ubwc_swizzle, -u32 ubwc_static, -u32 highest_bank_bit, -u32 macrotile_mode) +static void msm_mdss_setup_ubwc_dec_40(struct msm_mdss *msm_mdss) { - u32 value = (ubwc_swizzle & 0x7) | - (ubwc_static & 0x1) << 3 | - (highest_bank_bit & 0x7) << 4 | - (macrotile_mode & 0x1) << 12; + const struct msm_mdss_data *data = msm_mdss->mdss_data; + u32 value = (data->ubwc_swizzle & 0x7) | + (data->ubwc_static & 0x1) << 3 | + (data->highest_bank_bit & 0x7) << 4 | + (data->macrotile_mode & 0x1) << 12; writel_relaxed(value, msm_mdss->mmio + UBWC_STATIC); - if
Re: [PATCH] drm/msm: use strscpy instead of strncpy
On 1/17/2023 6:01 PM, Dmitry Baryshkov wrote: Using strncpy can result in non-NULL-terminated destination string. Use strscpy instead. This fixes following warning: drivers/gpu/drm/msm/msm_fence.c: In function ‘msm_fence_context_alloc’: drivers/gpu/drm/msm/msm_fence.c:25:9: warning: ‘strncpy’ specified bound 32 equals destination size [-Wstringop-truncation] 25 | strncpy(fctx->name, name, sizeof(fctx->name)); | ^ Fixes: f97decac5f4c ("drm/msm: Support multiple ringbuffers") Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/msm_fence.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_fence.c b/drivers/gpu/drm/msm/msm_fence.c index a47e5837c528..56641408ea74 100644 --- a/drivers/gpu/drm/msm/msm_fence.c +++ b/drivers/gpu/drm/msm/msm_fence.c @@ -22,7 +22,7 @@ msm_fence_context_alloc(struct drm_device *dev, volatile uint32_t *fenceptr, return ERR_PTR(-ENOMEM); fctx->dev = dev; - strncpy(fctx->name, name, sizeof(fctx->name)); + strscpy(fctx->name, name, sizeof(fctx->name)); fctx->context = dma_fence_context_alloc(1); fctx->index = index++; fctx->fenceptr = fenceptr;
Re: [PATCH v2] drm/msm/dpu: add missing ubwc_swizzle setting to catalog
On 1/22/2023 10:24 PM, Dmitry Baryshkov wrote: Use the values from the vendor DTs to set ubwc_swizzle in the catalog. Signed-off-by: Dmitry Baryshkov Matches all the vendor DTs, hence Reviewed-by: Abhinav Kumar --- Changes since v1: - Added data for sc7280 and sm8550 --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index e45799e9fe49..b16e550fc4b6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -580,6 +580,7 @@ static const struct dpu_mdp_cfg sm6115_mdp[] = { .base = 0x0, .len = 0x494, .features = 0, .highest_bank_bit = 0x1, + .ubwc_swizzle = 0x7, .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0}, .clk_ctrls[DPU_CLK_CTRL_DMA0] = { @@ -593,6 +594,7 @@ static const struct dpu_mdp_cfg sm8250_mdp[] = { .base = 0x0, .len = 0x494, .features = 0, .highest_bank_bit = 0x3, /* TODO: 2 for LP_DDR4 */ + .ubwc_swizzle = 0x6, .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2AC, .bit_off = 0}, .clk_ctrls[DPU_CLK_CTRL_VIG1] = { @@ -649,6 +651,7 @@ static const struct dpu_mdp_cfg sm8450_mdp[] = { .base = 0x0, .len = 0x494, .features = BIT(DPU_MDP_PERIPH_0_REMOVED), .highest_bank_bit = 0x3, /* TODO: 2 for LP_DDR4 */ + .ubwc_swizzle = 0x6, .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2AC, .bit_off = 0}, .clk_ctrls[DPU_CLK_CTRL_VIG1] = { @@ -675,6 +678,7 @@ static const struct dpu_mdp_cfg sc7280_mdp[] = { .name = "top_0", .id = MDP_TOP, .base = 0x0, .len = 0x2014, .highest_bank_bit = 0x1, + .ubwc_swizzle = 0x6, .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2AC, .bit_off = 0}, .clk_ctrls[DPU_CLK_CTRL_DMA0] = { @@ -711,6 +715,7 @@ static const struct dpu_mdp_cfg sm8550_mdp[] = { .base = 0, .len = 0x494, .features = BIT(DPU_MDP_PERIPH_0_REMOVED), .highest_bank_bit = 0x3, /* TODO: 2 for LP_DDR4 */ + .ubwc_swizzle = 0x6, .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x4330, .bit_off = 0}, .clk_ctrls[DPU_CLK_CTRL_VIG1] = {
Re: [PATCH] drm/msm/dpu: drop stale comment from struct dpu_mdp_cfg doc
On 1/21/2023 5:54 AM, Dmitry Baryshkov wrote: The field ubwc_static was removed from struct dpu_mdp_cfg some time ago. Drop the corresponding kerneldoc now. Fixes: 544d8b96150d ("drm/msm/dpu: update UBWC config for sm8150 and sm8250") Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index d152fef438f9..a56581b34ddf 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -539,7 +539,6 @@ struct dpu_clk_ctrl_reg { * @base: register base offset to mdss * @features bit mask identifying sub-blocks/features * @highest_bank_bit: UBWC parameter - * @ubwc_static: ubwc static configuration * @ubwc_swizzle: ubwc default swizzle setting * @clk_ctrls clock control register definition */
Re: [PATCH] drm/msm/dpu: disable features unsupported by QCM2290
On 1/22/2023 11:11 PM, Dmitry Baryshkov wrote: QCM2290 doesn't seem to support reg-dma, smart-dma, UBWC, CDP, exclusion rectangles and CSC. Drop corresponding features being incorrectly enabled for qcm2290. Can you please point me to which vendor DT you are referring to for this? CSC is supported on the VIG SSPPs from what I can see. QCM2290 should be using the same MDP version as 6115 from the HW version. Cc: Loic Poulain Fixes: 5334087ee743 ("drm/msm: add support for QCM2290 MDSS") Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 20 +++ 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 289fb11f99d1..1c3ffa922794 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -12,10 +12,14 @@ #include "dpu_hw_catalog.h" #include "dpu_kms.h" -#define VIG_MASK \ +#define VIG_BASE_MASK \ (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) |\ + BIT(DPU_SSPP_TS_PREFILL)) + +#define VIG_MASK \ + (VIG_BASE_MASK | \ BIT(DPU_SSPP_CSC_10BIT) | BIT(DPU_SSPP_CDP) |\ - BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_EXCL_RECT)) + BIT(DPU_SSPP_EXCL_RECT)) #define VIG_MSM8998_MASK \ (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3)) @@ -29,7 +33,7 @@ #define VIG_SM8250_MASK \ (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3LITE)) -#define VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL)) +#define VIG_QCM2290_MASK (VIG_BASE_MASK | BIT(DPU_SSPP_QOS_8LVL)) #define DMA_MSM8998_MASK \ (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) |\ @@ -50,6 +54,10 @@ #define DMA_CURSOR_MSM8998_MASK \ (DMA_MSM8998_MASK | BIT(DPU_SSPP_CURSOR)) +#define DMA_QCM2290_MASK \ + (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\ + BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1)) + #define MIXER_MSM8998_MASK \ (BIT(DPU_MIXER_SOURCESPLIT) | BIT(DPU_DIM_LAYER)) @@ -316,8 +324,6 @@ static const struct dpu_caps msm8998_dpu_caps = { static const struct dpu_caps qcm2290_dpu_caps = { .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .max_mixer_blendstages = 0x4, - .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, - .ubwc_version = DPU_HW_UBWC_VER_20, .has_dim_layer = true, .has_idle_pc = true, .max_linewidth = 2160, @@ -1384,7 +1390,7 @@ static const struct dpu_sspp_sub_blks qcm2290_dma_sblk_0 = _DMA_SBLK("8", 1); static const struct dpu_sspp_cfg qcm2290_sspp[] = { SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_QCM2290_MASK, qcm2290_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), - SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK, + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_QCM2290_MASK, qcm2290_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), }; @@ -2836,8 +2842,6 @@ static const struct dpu_mdss_cfg qcm2290_dpu_cfg = { .intf = qcm2290_intf, .vbif_count = ARRAY_SIZE(sdm845_vbif), .vbif = sdm845_vbif, - .reg_dma_count = 1, - .dma_cfg = _regdma, .perf = _perf_data, .mdss_irqs = IRQ_SC7180_MASK, };
Re: [PATCH] drm/msm/dpu: sc7180: add missing WB2 clock control
On 1/16/2023 2:30 AM, Dmitry Baryshkov wrote: Add missing DPU_CLK_CTRL_WB2 to sc7180_mdp clocks array. Fixes: 51e4d60e6ba5 ("drm/msm/dpu: add writeback support for sc7180") Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 504a22c76412..c7103b0445b6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -546,6 +546,8 @@ static const struct dpu_mdp_cfg sc7180_mdp[] = { .reg_off = 0x2B4, .bit_off = 8}, .clk_ctrls[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2C4, .bit_off = 8}, + .clk_ctrls[DPU_CLK_CTRL_WB2] = { + .reg_off = 0x3B8, .bit_off = 24}, }, };
Re: [PATCH] drm/msm/dpu: fix sm8450 CTL configuration
On 1/23/2023 12:08 AM, Dmitry Baryshkov wrote: Correct the CTL size on sm8450 platform. This fixes the incorrect merge of sm8350 support, which unfortunately also touched the SM8450 setup. Fixes: 0e91bcbb0016 ("drm/msm/dpu: Add SM8350 to hw catalog") Signed-off-by: Dmitry Baryshkov Matches the vendor DT size for sm8450, hence Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 63a0fa3b0a17..9060dce51e2e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -1017,31 +1017,31 @@ static const struct dpu_ctl_cfg sm8450_ctl[] = { }, { .name = "ctl_1", .id = CTL_1, - .base = 0x16000, .len = 0x1e8, + .base = 0x16000, .len = 0x204, .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), }, { .name = "ctl_2", .id = CTL_2, - .base = 0x17000, .len = 0x1e8, + .base = 0x17000, .len = 0x204, .features = CTL_SC7280_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11), }, { .name = "ctl_3", .id = CTL_3, - .base = 0x18000, .len = 0x1e8, + .base = 0x18000, .len = 0x204, .features = CTL_SC7280_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12), }, { .name = "ctl_4", .id = CTL_4, - .base = 0x19000, .len = 0x1e8, + .base = 0x19000, .len = 0x204, .features = CTL_SC7280_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13), }, { .name = "ctl_5", .id = CTL_5, - .base = 0x1a000, .len = 0x1e8, + .base = 0x1a000, .len = 0x204, .features = CTL_SC7280_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23), },
Re: [PATCH v1 04/14] drm/msm/dp: correct configure Colorimetry Indicator Field at MISC0
Hi Kuogee, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on next-20230123] [also build test WARNING on linus/master v6.2-rc5] [cannot apply to drm-misc/drm-misc-next drm/drm-next drm-exynos/exynos-drm-next drm-intel/for-linux-next drm-intel/for-linux-next-fixes drm-tip/drm-tip v6.2-rc5 v6.2-rc4 v6.2-rc3] [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#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Kuogee-Hsieh/drm-msm-dp-add-dpcd-read-of-both-dsc-and-fec-capability/20230124-022759 patch link: https://lore.kernel.org/r/1674498274-6010-5-git-send-email-quic_khsieh%40quicinc.com patch subject: [PATCH v1 04/14] drm/msm/dp: correct configure Colorimetry Indicator Field at MISC0 config: sparc-allyesconfig (https://download.01.org/0day-ci/archive/20230124/202301240836.ik3aytbc-...@intel.com/config) compiler: sparc64-linux-gcc (GCC) 12.1.0 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 # https://github.com/intel-lab-lkp/linux/commit/834f569a141af42cb93424c24e7d146f3b88405b git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Kuogee-Hsieh/drm-msm-dp-add-dpcd-read-of-both-dsc-and-fec-capability/20230124-022759 git checkout 834f569a141af42cb93424c24e7d146f3b88405b # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=sparc olddefconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=sparc SHELL=/bin/bash drivers/gpu/drm/msm/ If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot All warnings (new ones prefixed by >>): >> drivers/gpu/drm/msm/dp/dp_panel.c:571: warning: This comment starts with >> '/**', but isn't a kernel-doc comment. Refer >> Documentation/doc-guide/kernel-doc.rst * Mapper function which outputs colorimetry to be used for a vim +571 drivers/gpu/drm/msm/dp/dp_panel.c 569 570 /** > 571 * Mapper function which outputs colorimetry to be used for a 572 * given colorspace value when misc field of MSA is used to 573 * change the colorimetry. Currently only RGB formats have been 574 * added. This API will be extended to YUV once its supported on DP. 575 */ 576 u8 dp_panel_get_misc_colorimetry_val(struct dp_panel *dp_panel) 577 { 578 u8 colorimetry; 579 u32 colorspace; 580 u32 cc; 581 struct dp_panel_private *panel; 582 583 panel = container_of(dp_panel, struct dp_panel_private, dp_panel); 584 585 cc = dp_link_get_colorimetry_config(panel->link); 586 /* 587 * If there is a non-zero value then compliance test-case 588 * is going on, otherwise we can honor the colorspace setting 589 */ 590 if (cc) 591 return cc; 592 593 colorspace = dp_panel->connector->state->colorspace; 594 switch (colorspace) { 595 case DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65: 596 case DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER: 597 colorimetry = 0x7; 598 break; 599 case DRM_MODE_COLORIMETRY_RGB_WIDE_FIXED: 600 colorimetry = 0x3; 601 break; 602 case DRM_MODE_COLORIMETRY_RGB_WIDE_FLOAT: 603 colorimetry = 0xb; 604 break; 605 case DRM_MODE_COLORIMETRY_OPRGB: 606 colorimetry = 0xc; 607 break; 608 default: 609 colorimetry = 0; 610 } 611 612 return colorimetry; 613 } 614 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests
Re: [PATCH Resend v11 00/15] Add PSR support for eDP
On 19/01/2023 16:26, Vinod Polimera wrote: Changes in v2: - Use dp bridge to set psr entry/exit instead of dpu_enocder. - Don't modify whitespaces. - Set self refresh aware from atomic_check. - Set self refresh aware only if psr is supported. - Provide a stub for msm_dp_display_set_psr. - Move dp functions to bridge code. Changes in v3: - Change callback names to reflect atomic interfaces. - Move bridge callback change to separate patch as suggested by Dmitry. - Remove psr function declaration from msm_drv.h. - Set self_refresh_aware flag only if psr is supported. - Modify the variable names to simpler form. - Define bit fields for PSR settings. - Add comments explaining the steps to enter/exit psr. - Change DRM_INFO to drm_dbg_db. Changes in v4: - Move the get crtc functions to drm_atomic. - Add atomic functions for DP bridge too. - Add ternary operator to choose eDP or DP ops. - Return true/false instead of 1/0. - mode_valid missing in the eDP bridge ops. - Move the functions to get crtc into drm_atomic.c. - Fix compilation issues. - Remove dpu_assign_crtc and get crtc from drm_enc instead of dpu_enc. - Check for crtc state enable while reserving resources. Changes in v5: - Move the mode_valid changes into a different patch. - Complete psr_op_comp only when isr is set. - Move the DP atomic callback changes to a different patch. - Get crtc from drm connector state crtc. - Move to separate patch for check for crtc state enable while reserving resources. Changes in v6: - Remove crtc from dpu_encoder_virt struct. - fix crtc check during vblank toggle crtc. - Misc changes. Changes in v7: - Add fix for underrun issue on kasan build. Changes in v8: - Drop the enc spinlock as it won't serve any purpose in protetcing conn state.(Dmitry/Doug) Changes in v9: - Update commit message and fix alignment using spaces.(Marijn) - Misc changes.(Marijn) Changes in v10: - Get crtc cached in dpu_enc during obj init.(Dmitry) Changes in v11: - Remove crtc cached in dpu_enc during obj init. - Update dpu_enc crtc state on crtc enable/disable during self refresh. Sankeerth Billakanti (1): drm/msm/dp: disable self_refresh_aware after entering psr Vinod Polimera (14): drm: add helper functions to retrieve old and new crtc drm/msm/dp: use atomic callbacks for DP bridge ops drm/msm/dp: Add basic PSR support for eDP drm/msm/dp: use the eDP bridge ops to validate eDP modes drm/bridge: use atomic enable/disable callbacks for panel bridge drm/bridge: add psr support for panel bridge callbacks drm/msm/disp/dpu: use atomic enable/disable callbacks for encoder functions drm/msm/disp/dpu: check for crtc enable rather than crtc active to release shared resources drm/msm/disp/dpu: add PSR support for eDP interface in dpu driver drm/msm/disp/dpu: get timing engine status from intf status register drm/msm/disp/dpu: wait for extra vsync till timing engine status is disabled drm/msm/disp/dpu: reset the datapath after timing engine disable drm/msm/disp/dpu: clear active interface in the datapath cleanup drm/msm/disp/dpu: update dpu_enc crtc state on crtc enable/disable during self refresh 1) Please move core patches to the beginning of the series, so that it is possible to pick them up separately 2) Please follow Daniel's comment in https://lore.kernel.org/all/Y7bMcLHr79uhfJv2@phenom.ffwll.local/ and apply corresponding Reviewed-by tags. drivers/gpu/drm/bridge/panel.c | 68 ++- drivers/gpu/drm/drm_atomic.c | 60 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 42 - drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 29 ++- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 22 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 3 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 12 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c| 8 +- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c| 2 +- drivers/gpu/drm/msm/dp/dp_catalog.c| 80 + drivers/gpu/drm/msm/dp/dp_catalog.h| 4 + drivers/gpu/drm/msm/dp/dp_ctrl.c | 80 + drivers/gpu/drm/msm/dp/dp_ctrl.h | 3 + drivers/gpu/drm/msm/dp/dp_display.c| 36 ++-- drivers/gpu/drm/msm/dp/dp_display.h| 2 + drivers/gpu/drm/msm/dp/dp_drm.c| 196 - drivers/gpu/drm/msm/dp/dp_drm.h| 9 +- drivers/gpu/drm/msm/dp/dp_link.c | 36 drivers/gpu/drm/msm/dp/dp_panel.c | 22 +++ drivers/gpu/drm/msm/dp/dp_panel.h | 6 + drivers/gpu/drm/msm/dp/dp_reg.h| 27 +++ include/drm/drm_atomic.h | 7 + 22 files changed, 710
Re: [PATCH Resend v11 15/15] drm/msm/disp/dpu: update dpu_enc crtc state on crtc enable/disable during self refresh
On 19/01/2023 16:26, Vinod Polimera wrote: Populate the enocder software structure to reflect the updated crtc appropriately during crtc enable/disable for a new commit while taking care of the self refresh transitions when crtc disable is triggered from the drm self refresh library. Signed-off-by: Vinod Polimera --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 31 ++- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index d513aeb4..e8e456a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -1013,14 +1013,23 @@ static void dpu_crtc_disable(struct drm_crtc *crtc, crtc); struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state); - struct drm_encoder *encoder; + struct drm_encoder *encoder = NULL; Why is this chunk necessary? unsigned long flags; bool release_bandwidth = false; DRM_DEBUG_KMS("crtc%d\n", crtc->base.id); - if (old_crtc_state->self_refresh_active) + /* If disable is triggered while in self refresh mode, +* reset the encoder software state so that in enable +* it won't trigger a warn while assigning crtc. +*/ + if (old_crtc_state->self_refresh_active) { + drm_for_each_encoder_mask(encoder, crtc->dev, + old_crtc_state->encoder_mask) { + dpu_encoder_assign_crtc(encoder, NULL); + } return; + } /* Disable/save vblank irq handling */ drm_crtc_vblank_off(crtc); @@ -1033,7 +1042,14 @@ static void dpu_crtc_disable(struct drm_crtc *crtc, */ if (dpu_encoder_get_intf_mode(encoder) == INTF_MODE_VIDEO) release_bandwidth = true; - dpu_encoder_assign_crtc(encoder, NULL); + + /* +* If disable is triggered during psr active(e.g: screen dim in PSR), +* we will need encoder->crtc connection to process the device sleep & +* preserve it during psr sequence. +*/ + if (!crtc->state->self_refresh_active) + dpu_encoder_assign_crtc(encoder, NULL); } /* wait for frame_event_done completion */ @@ -1081,6 +1097,9 @@ static void dpu_crtc_enable(struct drm_crtc *crtc, struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); struct drm_encoder *encoder; bool request_bandwidth = false; + struct drm_crtc_state *old_crtc_state; + + old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc); pm_runtime_get_sync(crtc->dev->dev); @@ -1103,8 +1122,10 @@ static void dpu_crtc_enable(struct drm_crtc *crtc, trace_dpu_crtc_enable(DRMID(crtc), true, dpu_crtc); dpu_crtc->enabled = true; - drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) - dpu_encoder_assign_crtc(encoder, crtc); + if (!old_crtc_state->self_refresh_active) { + drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) + dpu_encoder_assign_crtc(encoder, crtc); + } /* Enable/restore vblank irq handling */ drm_crtc_vblank_on(crtc); -- With best wishes Dmitry
Re: [PATCH Resend v11 14/15] drm/msm/disp/dpu: clear active interface in the datapath cleanup
On 19/01/2023 16:26, Vinod Polimera wrote: Clear interface active register from the datapath for a clean shutdown of the datapath. Signed-off-by: Vinod Polimera --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 9cf1263..30dee50 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -2085,6 +2085,9 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) if (phys_enc->hw_pp->merge_3d) intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx; + if (phys_enc->hw_intf) + intf_cfg.intf = phys_enc->hw_intf->idx; + if (ctl->ops.reset_intf_cfg) ctl->ops.reset_intf_cfg(ctl, _cfg); This is already handled as a part of the commit 9811913a6dd0 ("drm/msm/dpu: populate wb or intf before reset_intf_cfg") -- With best wishes Dmitry
Re: [PATCH Resend v11 13/15] drm/msm/disp/dpu: reset the datapath after timing engine disable
On 19/01/2023 16:26, Vinod Polimera wrote: Reset the datapath after disabling the timing gen, such that it can start on a clean slate when the intf is enabled back. This was a recommended sequence from the DPU HW programming guide. Signed-off-by: Vinod Polimera --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 1 + 1 file changed, 1 insertion(+) Reviewed-by: Dmitry Baryshkov -- With best wishes Dmitry
Re: [PATCH Resend v11 12/15] drm/msm/disp/dpu: wait for extra vsync till timing engine status is disabled
On 19/01/2023 16:26, Vinod Polimera wrote: There can be a race between timing gen disable and vblank irq. The wait post timing gen disable may return early but intf disable sequence might not be completed. Ensure that, intf status is disabled before we retire the function. Signed-off-by: Vinod Polimera Reviewed-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c| 21 + 1 file changed, 21 insertions(+) -- With best wishes Dmitry
Re: [PATCH Resend v11 11/15] drm/msm/disp/dpu: get timing engine status from intf status register
On 19/01/2023 16:26, Vinod Polimera wrote: Recommended way of reading the interface timing gen status is via status register. Timing gen status register will give a reliable status of the interface especially during ON/OFF transitions. This support was added from DPU version 5.0.0. 5.0.0 is sm8150. I have expected to see INTF_SC7180_MASK to be changed, while this patch for some reason changes only INTF_SC7280_MASK. Could you please clarify this? Signed-off-by: Vinod Polimera --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 3 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 12 +++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c| 8 +++- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 4375e72..0244a7b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -80,7 +80,8 @@ #define INTF_SC7180_MASK BIT(DPU_INTF_INPUT_CTRL) | BIT(DPU_INTF_TE) -#define INTF_SC7280_MASK INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN) +#define INTF_SC7280_MASK \ + (INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN) | BIT(DPU_INTF_STATUS_SUPPORTED)) #define IRQ_SDM845_MASK (BIT(MDP_SSPP_TOP0_INTR) | \ BIT(MDP_SSPP_TOP0_INTR2) | \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 978e3bd..79c18fe 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -213,17 +213,19 @@ enum { /** * INTF sub-blocks - * @DPU_INTF_INPUT_CTRL Supports the setting of pp block from which - * pixel data arrives to this INTF - * @DPU_INTF_TE INTF block has TE configuration support - * @DPU_DATA_HCTL_ENAllows data to be transferred at different rate -than video timing + * @DPU_INTF_INPUT_CTRL Supports the setting of pp block from which + * pixel data arrives to this INTF + * @DPU_INTF_TE INTF block has TE configuration support + * @DPU_DATA_HCTL_ENAllows data to be transferred at different rate + * than video timing + * @DPU_INTF_STATUS_SUPPORTED INTF block has INTF_STATUS register * @DPU_INTF_MAX */ enum { DPU_INTF_INPUT_CTRL = 0x1, DPU_INTF_TE, DPU_DATA_HCTL_EN, + DPU_INTF_STATUS_SUPPORTED, DPU_INTF_MAX }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c index 7ce66bf..84ee2ef 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -62,6 +62,7 @@ #define INTF_LINE_COUNT 0x0B0 #define INTF_MUX 0x25C +#define INTF_STATUS 0x26C #define INTF_CFG_ACTIVE_H_EN BIT(29) #define INTF_CFG_ACTIVE_V_EN BIT(30) @@ -297,8 +298,13 @@ static void dpu_hw_intf_get_status( struct intf_status *s) { struct dpu_hw_blk_reg_map *c = >hw; + unsigned long cap = intf->cap->features; + + if (cap & BIT(DPU_INTF_STATUS_SUPPORTED)) + s->is_en = DPU_REG_READ(c, INTF_STATUS) & BIT(0); + else + s->is_en = DPU_REG_READ(c, INTF_TIMING_ENGINE_EN); - s->is_en = DPU_REG_READ(c, INTF_TIMING_ENGINE_EN); s->is_prog_fetch_en = !!(DPU_REG_READ(c, INTF_CONFIG) & BIT(31)); if (s->is_en) { s->frame_count = DPU_REG_READ(c, INTF_FRAME_COUNT); -- With best wishes Dmitry
Re: [PATCH Resend v11 05/15] drm/msm/dp: disable self_refresh_aware after entering psr
On 19/01/2023 16:26, Vinod Polimera wrote: From: Sankeerth Billakanti Updated frames get queued if self_refresh_aware is set when the sink is in psr. To support bridge enable and avoid queuing of update frames, reset the self_refresh_aware state after entering psr. I'm not convinced by this change. E.g. analogix code doesn't do this. Could you please clarify, why do you need to toggle the self_refresh_aware flag? Signed-off-by: Sankeerth Billakanti Signed-off-by: Vinod Polimera --- drivers/gpu/drm/msm/dp/dp_drm.c | 27 ++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c index 029e08c..92d1a1b 100644 --- a/drivers/gpu/drm/msm/dp/dp_drm.c +++ b/drivers/gpu/drm/msm/dp/dp_drm.c @@ -134,6 +134,8 @@ static void edp_bridge_atomic_enable(struct drm_bridge *drm_bridge, struct drm_crtc_state *old_crtc_state; struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge); struct msm_dp *dp = dp_bridge->dp_display; + struct drm_connector *connector; + struct drm_connector_state *conn_state = NULL; /* * Check the old state of the crtc to determine if the panel @@ -150,10 +152,22 @@ static void edp_bridge_atomic_enable(struct drm_bridge *drm_bridge, if (old_crtc_state && old_crtc_state->self_refresh_active) { dp_display_set_psr(dp, false); - return; + goto psr_aware; } dp_bridge_atomic_enable(drm_bridge, old_bridge_state); + +psr_aware: + connector = drm_atomic_get_new_connector_for_encoder(atomic_state, + drm_bridge->encoder); + if (connector) + conn_state = drm_atomic_get_new_connector_state(atomic_state, + connector); + + if (conn_state) { + conn_state->self_refresh_aware = dp->psr_supported; + } No need to wrap a single line statement in brackets. + } static void edp_bridge_atomic_disable(struct drm_bridge *drm_bridge, @@ -164,6 +178,14 @@ static void edp_bridge_atomic_disable(struct drm_bridge *drm_bridge, struct drm_crtc_state *new_crtc_state = NULL, *old_crtc_state = NULL; struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge); struct msm_dp *dp = dp_bridge->dp_display; + struct drm_connector *connector; + struct drm_connector_state *conn_state = NULL; + + connector = drm_atomic_get_old_connector_for_encoder(atomic_state, + drm_bridge->encoder); + if (connector) + conn_state = drm_atomic_get_new_connector_state(atomic_state, + connector); crtc = drm_atomic_get_old_crtc_for_encoder(atomic_state, drm_bridge->encoder); @@ -190,6 +212,9 @@ static void edp_bridge_atomic_disable(struct drm_bridge *drm_bridge, * when display disable occurs while the sink is in psr state. */ if (new_crtc_state->self_refresh_active) { + if (conn_state) + conn_state->self_refresh_aware = false; + dp_display_set_psr(dp, true); return; } else if (old_crtc_state->self_refresh_active) { -- With best wishes Dmitry
Re: [PATCH v2 8/9] drm/i915/pxp: On MTL, KCR enabling doesn't wait on tee component
Thanks - will go with your suggestion - ditch all the abstraction / consolidation .. add only the two additional calls with the explicit runtime-takes - that minimizes the changes. And won't forget to the fix the '&' -> '&&' ...alan On Wed, 2023-01-18 at 18:17 -0800, Ceraolo Spurio, Daniele wrote: > > > On 1/11/2023 1:42 PM, Alan Previn wrote: > > On legacy platforms, KCR HW enabling is done at the time the mei > > component interface is bound. It's also disabled during unbind. > > However, for MTL onwards, we don't depend on the tee-component > > operation before we can start sending GSC-CS firmware messages. > > > > Thus, immediately enable KCR HW on PXP's init, fini and resume. alan:snip..
Re: [PATCH drm-next 03/14] drm: manager to keep track of GPUs VA mappings
On 1/24/23 00:23, Niranjana Vishwanathapura wrote: On Wed, Jan 18, 2023 at 07:12:45AM +0100, Danilo Krummrich wrote: This adds the infrastructure for a manager implementation to keep track of GPU virtual address (VA) mappings. New UAPIs, motivated by Vulkan sparse memory bindings graphics drivers start implementing, allow userspace applications to request multiple and arbitrary GPU VA mappings of buffer objects. The DRM GPU VA manager is intended to serve the following purposes in this context. 1) Provide a dedicated range allocator to track GPU VA allocations and mappings, making use of the drm_mm range allocator. 2) Generically connect GPU VA mappings to their backing buffers, in particular DRM GEM objects. 3) Provide a common implementation to perform more complex mapping operations on the GPU VA space. In particular splitting and merging of GPU VA mappings, e.g. for intersecting mapping requests or partial unmap requests. Idea-suggested-by: Dave Airlie Signed-off-by: Danilo Krummrich --- Documentation/gpu/drm-mm.rst | 31 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/drm_gem.c | 3 + drivers/gpu/drm/drm_gpuva_mgr.c | 1323 +++ include/drm/drm_drv.h | 6 + include/drm/drm_gem.h | 75 ++ include/drm/drm_gpuva_mgr.h | 527 7 files changed, 1966 insertions(+) create mode 100644 drivers/gpu/drm/drm_gpuva_mgr.c create mode 100644 include/drm/drm_gpuva_mgr.h diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst index a52e6f4117d6..c9f120cfe730 100644 --- a/Documentation/gpu/drm-mm.rst +++ b/Documentation/gpu/drm-mm.rst @@ -466,6 +466,37 @@ DRM MM Range Allocator Function References .. kernel-doc:: drivers/gpu/drm/drm_mm.c :export: +DRM GPU VA Manager +== + +Overview + + +.. kernel-doc:: drivers/gpu/drm/drm_gpuva_mgr.c + :doc: Overview + +Split and Merge +--- + +.. kernel-doc:: drivers/gpu/drm/drm_gpuva_mgr.c + :doc: Split and Merge + +Locking +--- + +.. kernel-doc:: drivers/gpu/drm/drm_gpuva_mgr.c + :doc: Locking + + +DRM GPU VA Manager Function References +-- + +.. kernel-doc:: include/drm/drm_gpuva_mgr.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_gpuva_mgr.c + :export: + DRM Buddy Allocator === diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 4fe190aee584..de2ffca3b6e4 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -45,6 +45,7 @@ drm-y := \ drm_vblank.o \ drm_vblank_work.o \ drm_vma_manager.o \ + drm_gpuva_mgr.o \ drm_writeback.o drm-$(CONFIG_DRM_LEGACY) += \ drm_agpsupport.o \ diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 59a0bb5ebd85..65115fe88627 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -164,6 +164,9 @@ void drm_gem_private_object_init(struct drm_device *dev, if (!obj->resv) obj->resv = >_resv; + if (drm_core_check_feature(dev, DRIVER_GEM_GPUVA)) + drm_gem_gpuva_init(obj); + drm_vma_node_reset(>vma_node); INIT_LIST_HEAD(>lru_node); } diff --git a/drivers/gpu/drm/drm_gpuva_mgr.c b/drivers/gpu/drm/drm_gpuva_mgr.c new file mode 100644 index ..e665f642689d --- /dev/null +++ b/drivers/gpu/drm/drm_gpuva_mgr.c @@ -0,0 +1,1323 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 Red Hat. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Danilo Krummrich + * + */ + +#include +#include + +/** + * DOC: Overview + * + * The DRM GPU VA Manager, represented by struct drm_gpuva_manager keeps track + * of a GPU's virtual address (VA) space and manages the corresponding virtual + * mappings represented by _gpuva objects. It also keeps track of the + * mapping's backing _gem_object buffers. + * + * _gem_object buffers
Re: [PATCH v1 00/14] add display port DSC feature
On 23/01/2023 20:24, Kuogee Hsieh wrote: This patch add DSC related supporting functions into to both dp controller and dpu enccoder Kuogee Hsieh (14): drm/msm/dp: add dpcd read of both dsc and fec capability drm/msm/dp: add dsc factor into calculation of supported bpp drm/msm/dp: add configure mainlink_levels base on lane number drm/msm/dp: correct configure Colorimetry Indicator Field at MISC0 drm/msm/dp: upgrade tu calculation base on newest algorithm drm/msm/dp: add display compression related struct drm/msm/dp: add dsc helper functions drm/msm/dp: add dsc supporting functions to DP controller drm/msm/dsi: export struct msm_compression_info to dpu encoder drm/msm/disp/dpu: add supports of DSC encoder v1.2 engine drm/msm/disp/dpu1: add supports of new flush mechanism drm/msm/disp/dpu1: revise timing engine programming to work for DSC drm/msm/disp/dpu1: add dsc supporting functions to dpu encoder drm/msm/disp/dpu1: add sc7280 dsc block and sub block Some generic notes regarding the series. I understand that the the series is complex, but following points might ease both your work and the review proces. First, atomicity. If your commit message says 'do this and that', it is highly likely that the patch should be split into smaller parts. Second, please pay attention to the history. If some part of the code or the data structure was removed, you have to justify bringing it back. This is extremely important in your case, as significant parts of the code come from the vendor code, thut it is easy to step on the same rake again. And if the previous removal was incorrect, please describe why. If we went through 10 revisions of a patch a year ago, it's not worth sending again a patch that closely remedies one of early iterations. It doesn't stand a chance of getting through. Next. Obvious item. ./scripts/checkpatch.pl should be your friend. It is not. Last, but not least. Please follow the mailing list. Less than a week ago one of reviews pointed out that commit messages like 'this patch does this and that' are not really welcomed. By sending the same kind of commit messages, you stand a high chance of receiveing the same response. Please go through the recommendations in Documentation/process/submitting-patches.rst. drivers/gpu/drm/msm/Makefile | 2 + drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.c | 537 + drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.h | 25 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 341 +++-- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h| 4 +- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 7 +- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 43 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 50 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 74 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 43 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 21 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 23 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 23 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 371 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c| 132 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h| 10 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h| 3 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h | 6 +- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c| 10 +- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 10 +- drivers/gpu/drm/msm/dp/dp_catalog.c| 176 - drivers/gpu/drm/msm/dp/dp_catalog.h| 97 ++- drivers/gpu/drm/msm/dp/dp_ctrl.c | 839 ++--- drivers/gpu/drm/msm/dp/dp_display.c| 61 +- drivers/gpu/drm/msm/dp/dp_link.c | 29 +- drivers/gpu/drm/msm/dp/dp_panel.c | 749 +- drivers/gpu/drm/msm/dp/dp_panel.h | 67 +- drivers/gpu/drm/msm/dp/dp_reg.h| 40 +- drivers/gpu/drm/msm/dsi/dsi.c | 3 +- drivers/gpu/drm/msm/dsi/dsi.h | 3 +- drivers/gpu/drm/msm/dsi/dsi_host.c | 14 +- drivers/gpu/drm/msm/msm_drv.h | 113 ++- 32 files changed, 3429 insertions(+), 497 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c -- With best wishes Dmitry
Re: [PATCH v1 05/14] drm/msm/dp: upgrade tu calculation base on newest algorithm
Hi Kuogee, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on next-20230123] [also build test WARNING on linus/master v6.2-rc5] [cannot apply to drm-misc/drm-misc-next drm/drm-next drm-exynos/exynos-drm-next drm-intel/for-linux-next drm-intel/for-linux-next-fixes drm-tip/drm-tip v6.2-rc5 v6.2-rc4 v6.2-rc3] [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#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Kuogee-Hsieh/drm-msm-dp-add-dpcd-read-of-both-dsc-and-fec-capability/20230124-022759 patch link: https://lore.kernel.org/r/1674498274-6010-6-git-send-email-quic_khsieh%40quicinc.com patch subject: [PATCH v1 05/14] drm/msm/dp: upgrade tu calculation base on newest algorithm config: m68k-allmodconfig (https://download.01.org/0day-ci/archive/20230124/202301240854.5yjvg3rr-...@intel.com/config) compiler: m68k-linux-gcc (GCC) 12.1.0 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 # https://github.com/intel-lab-lkp/linux/commit/286a3dd6028ada56b471b5cb977f5ed461b094e4 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Kuogee-Hsieh/drm-msm-dp-add-dpcd-read-of-both-dsc-and-fec-capability/20230124-022759 git checkout 286a3dd6028ada56b471b5cb977f5ed461b094e4 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k olddefconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k SHELL=/bin/bash drivers/gpu/drm/msm/ If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot All warnings (new ones prefixed by >>): drivers/gpu/drm/msm/dp/dp_ctrl.c: In function '_tu_param_compare': drivers/gpu/drm/msm/dp/dp_ctrl.c:282:20: warning: variable 'b_frac' set but not used [-Wunused-but-set-variable] 282 | u32 b_int, b_frac, b_sign; |^~ drivers/gpu/drm/msm/dp/dp_ctrl.c:282:13: warning: variable 'b_int' set but not used [-Wunused-but-set-variable] 282 | u32 b_int, b_frac, b_sign; | ^ drivers/gpu/drm/msm/dp/dp_ctrl.c:281:20: warning: variable 'a_frac' set but not used [-Wunused-but-set-variable] 281 | u32 a_int, a_frac, a_sign; |^~ drivers/gpu/drm/msm/dp/dp_ctrl.c:281:13: warning: variable 'a_int' set but not used [-Wunused-but-set-variable] 281 | u32 a_int, a_frac, a_sign; | ^ drivers/gpu/drm/msm/dp/dp_ctrl.c: In function 'dp_panel_update_tu_timings': drivers/gpu/drm/msm/dp/dp_ctrl.c:344:13: warning: variable 'overhead_dsc' set but not used [-Wunused-but-set-variable] 344 | s64 overhead_dsc; | ^~~~ In file included from drivers/gpu/drm/msm/dp/dp_ctrl.c:18: drivers/gpu/drm/msm/dp/dp_ctrl.c: In function '_dp_ctrl_calc_tu': drivers/gpu/drm/msm/dp/dp_ctrl.c:823:27: warning: format '%d' expects argument of type 'int', but argument 4 has type 's64' {aka 'long long int'} [-Wformat=] 823 | DRM_DEBUG("Info: increase HBLANK_MARGIN to %d. (PLUS%d)\n", HBLANK_MARGIN, | ^~~~ ~ | | | s64 {aka long long int} include/drm/drm_print.h:524:65: note: in definition of macro '__drm_dbg' 524 | #define __drm_dbg(fmt, ...) ___drm_dbg(NULL, fmt, ##__VA_ARGS__) | ^~~ drivers/gpu/drm/msm/dp/dp_ctrl.c:823:17: note: in expansion of macro 'DRM_DEBUG' 823 | DRM_DEBUG("Info: increase HBLANK_MARGIN to %d. (PLUS%d)\n", HBLANK_MARGIN, | ^ drivers/gpu/drm/msm/dp/dp_ctrl.c:823:61: note: format string is defined here 823 | DRM_DEBUG("Info: increase HBLANK_MARGIN to %d. (PLUS%d)\n", HBLANK_MARGIN, |~^ | | | int |%lld drivers/gpu/drm/msm/dp/dp_ctrl.c:823:27: warning: format '%d' expects argument of type 'int', but a
Re: [PATCH 2/2] media: uvcvideo: expose dma-heap hint to userspace
Hi Christian, I love your patch! Perhaps something to improve: [auto build test WARNING on drm-misc/drm-misc-next] [also build test WARNING on media-tree/master drm-tip/drm-tip linus/master v6.2-rc5] [cannot apply to next-20230123] [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#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Christian-K-nig/media-uvcvideo-expose-dma-heap-hint-to-userspace/20230123-213836 base: git://anongit.freedesktop.org/drm/drm-misc drm-misc-next patch link: https://lore.kernel.org/r/20230123123756.401692-3-christian.koenig%40amd.com patch subject: [PATCH 2/2] media: uvcvideo: expose dma-heap hint to userspace config: hexagon-randconfig-r032-20230123 (https://download.01.org/0day-ci/archive/20230124/202301240717.tim1ggho-...@intel.com/config) compiler: clang version 16.0.0 (https://github.com/llvm/llvm-project 4196ca3278f78c6e19246e54ab0ecb364e37d66a) 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 # https://github.com/intel-lab-lkp/linux/commit/adc04dccd892eec7f84c6ec112b48df376172e48 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Christian-K-nig/media-uvcvideo-expose-dma-heap-hint-to-userspace/20230123-213836 git checkout adc04dccd892eec7f84c6ec112b48df376172e48 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon olddefconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon SHELL=/bin/bash drivers/media/usb/uvc/ If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot All warnings (new ones prefixed by >>): In file included from drivers/media/usb/uvc/uvc_driver.c:10: >> include/linux/dma-heap.h:92:5: warning: no previous prototype for function >> 'dma_heap_create_device_link' [-Wmissing-prototypes] int dma_heap_create_device_link(struct device *dev, const char *heap) ^ include/linux/dma-heap.h:92:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int dma_heap_create_device_link(struct device *dev, const char *heap) ^ static >> include/linux/dma-heap.h:97:6: warning: no previous prototype for function >> 'dma_heap_remove_device_link' [-Wmissing-prototypes] void dma_heap_remove_device_link(struct device *dev) ^ include/linux/dma-heap.h:97:1: note: declare 'static' if the function is not intended to be used outside of this translation unit void dma_heap_remove_device_link(struct device *dev) ^ static In file included from drivers/media/usb/uvc/uvc_driver.c:16: In file included from include/linux/usb.h:16: In file included from include/linux/interrupt.h:11: In file included from include/linux/hardirq.h:11: In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/hexagon/include/asm/io.h:334: include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __raw_readb(PCI_IOBASE + addr); ~~ ^ include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr)); ~~ ^ include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu' #define __le16_to_cpu(x) ((__force __u16)(__le16)(x)) ^ In file included from drivers/media/usb/uvc/uvc_driver.c:16: In file included from include/linux/usb.h:16: In file included from include/linux/interrupt.h:11: In file included from include/linux/hardirq.h:11: In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/hexagon/include/asm/io.h:334: include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __le32_to_cpu((__le32
Re: [PATCH v1 05/14] drm/msm/dp: upgrade tu calculation base on newest algorithm
On 23/01/2023 20:24, Kuogee Hsieh wrote: At display port, the pixel data is packed into TU (transfer units) which is used to carry main video stream data during its horizontal active period. TUs are mapping into the main-Link to facilitate the support of various lane counts regardless of the pixel bit depth and colorimetry format. Stuffing symbols are required if packed data rate less than link symbol rate. TU size is calculated base on factors such as, pixel rate, BPP, main link rate, main link lane and etc, and shall be 32 to 64 link symbols per lane. Each vendor has its own algorithm to calculate TU size. This patch upgrade TU size calculation base on newest algorithm. Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/dp/dp_ctrl.c | 702 +++ 1 file changed, 416 insertions(+), 286 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c index d0d1848..ae9c2b8 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -182,18 +182,24 @@ static void dp_ctrl_configure_source_params(struct dp_ctrl_private *ctrl) */ struct tu_algo_data { s64 lclk_fp; + s64 orig_lclk_fp; s64 pclk_fp; + s64 orig_pclk_fp; s64 lwidth; s64 lwidth_fp; + int orig_lwidth; s64 hbp_relative_to_pclk; s64 hbp_relative_to_pclk_fp; int nlanes; + int orig_hbp; int bpp; int pixelEnc; int dsc_en; int async_en; + int fec_en; int bpc; + int rb2; uint delay_start_link_extra_pixclk; int extra_buffer_margin; s64 ratio_fp; @@ -250,19 +256,30 @@ struct tu_algo_data { int even_distribution_BF; int even_distribution_legacy; int even_distribution; + + int hbp_delayStartCheck; + int pre_tu_hw_pipe_delay; + int post_tu_hw_pipe_delay; + int link_config_hactive_time; + int delay_start_link_lclk; + int tu_active_cycles; + s64 parity_symbols; + int resolution_line_time; + int last_partial_lclk; + int min_hblank_violated; s64 delay_start_time_fp; s64 hbp_time_fp; s64 hactive_time_fp; s64 diff_abs_fp; - + int second_loop_set; s64 ratio; }; static int _tu_param_compare(s64 a, s64 b) { - u32 a_sign; - u32 b_sign; + u32 a_int, a_frac, a_sign; + u32 b_int, b_frac, b_sign; s64 a_temp, b_temp, minus_1; if (a == b) @@ -270,8 +287,12 @@ static int _tu_param_compare(s64 a, s64 b) minus_1 = drm_fixp_from_fraction(-1, 1); + a_int = (a >> 32) & 0x7FFF; + a_frac = a & 0x; a_sign = (a >> 32) & 0x8000 ? 1 : 0; + b_int = (b >> 32) & 0x7FFF; + b_frac = b & 0x; b_sign = (b >> 32) & 0x8000 ? 1 : 0; if (a_sign > b_sign) @@ -295,6 +316,21 @@ static int _tu_param_compare(s64 a, s64 b) } } +static s64 fixp_subtract(s64 a, s64 b) +{ + s64 minus_1 = drm_fixp_from_fraction(-1, 1); + + if (a >= b) + return a - b; + + return drm_fixp_mul(b - a, minus_1); +} + +static inline int fixp2int_ceil(s64 a) +{ + return a ? drm_fixp2int_ceil(a) : 0; +} + static void dp_panel_update_tu_timings(struct dp_tu_calc_input *in, struct tu_algo_data *tu) { @@ -305,6 +341,7 @@ static void dp_panel_update_tu_timings(struct dp_tu_calc_input *in, s64 pclk_dsc_fp; s64 dwidth_dsc_fp; s64 hbp_dsc_fp; + s64 overhead_dsc; int tot_num_eoc_symbols = 0; int tot_num_hor_bytes = 0; @@ -315,16 +352,22 @@ static void dp_panel_update_tu_timings(struct dp_tu_calc_input *in, s64 temp1_fp, temp2_fp, temp3_fp; tu->lclk_fp = drm_fixp_from_fraction(in->lclk, 1); + tu->orig_lclk_fp = tu->lclk_fp; tu->pclk_fp = drm_fixp_from_fraction(in->pclk_khz, 1000); + tu->orig_pclk_fp = tu->pclk_fp; tu->lwidth = in->hactive; tu->hbp_relative_to_pclk = in->hporch; tu->nlanes = in->nlanes; tu->bpp = in->bpp; tu->pixelEnc = in->pixel_enc; tu->dsc_en = in->dsc_en; + tu->fec_en = in->fec_en; tu->async_en = in->async_en; tu->lwidth_fp= drm_fixp_from_fraction(in->hactive, 1); + tu->orig_lwidth = in->hactive; tu->hbp_relative_to_pclk_fp = drm_fixp_from_fraction(in->hporch, 1); + tu->orig_hbp = in->hporch; + tu->rb2 = (in->hporch <= 80) ? 1 : 0; if (tu->pixelEnc == 420) { temp1_fp = drm_fixp_from_fraction(2, 1); @@ -378,6 +421,7 @@ static void dp_panel_update_tu_timings(struct dp_tu_calc_input *in, dwidth_dsc_bytes = (tot_num_hor_bytes +
Re: [ANNOUNCE] pixfmtdb
On Mon, Jan 23, 2023 at 11:43 PM Simon Ser wrote: > > On Monday, January 23rd, 2023 at 21:25, Sebastian Wick > wrote: > > > Why is the TF defined for GL formats and both the primaries and TF for > > Vulkan formats? The only exception here should be sRGB formats. Where > > did you get the information from? > > This is what upstream dfdutils does [1]. Can you explain why you think > it should be undefined instead of linear? The channels have no meaning. You can put whatever you want in there. It doesn't have to be linear, it doesn't have to be colors and especially not colors with specific primaries. It's only when it's used to form an image that the TF and primaries are known. Vulkan specifically requires you to explicitly provide this information to the WSI and YCC samplers (generally everywhere where knowing them is required) and never assumes that certain pixel formats imply certain TFs and primaries (exception being the sRGB variants). (See also https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#_issues_26, Q 23) The problem here seems to be that the Data Format spec describes more than the pixel format. If you want to share an image, the TF and primaries are essential but they are not an inherent part of the pixel format of the image. So yeah, I think what dfdutils does is... probably not wrong but not what you're after. > > I was wondering what to do for DRM formats regarding these. I think it > would be worthwhile to do like Vulkan: set TF = linear, primaries = > BT.709, pre-multiplied alpha = yes. These are the things KMS assume > when there is no override (ie, when there is no KMS property saying > otherwise). Please no. All undefined is absolutely the right thing to do. Adding any more meaning to pixel formats is a horrible idea. The KMS properties are also not an override, they describe the image and the description has default values. > > [1]: > https://github.com/KhronosGroup/dfdutils/blob/5cd41cbdf63e80b00c085c6906a1152709e4c0f2/createdfd.c#L47 >
Re: [PATCH v1 02/14] drm/msm/dp: add dsc factor into calculation of supported bpp
Hi Kuogee, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on next-20230123] [also build test WARNING on linus/master v6.2-rc5] [cannot apply to drm-misc/drm-misc-next drm/drm-next drm-exynos/exynos-drm-next drm-intel/for-linux-next drm-intel/for-linux-next-fixes drm-tip/drm-tip v6.2-rc5 v6.2-rc4 v6.2-rc3] [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#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Kuogee-Hsieh/drm-msm-dp-add-dpcd-read-of-both-dsc-and-fec-capability/20230124-022759 patch link: https://lore.kernel.org/r/1674498274-6010-3-git-send-email-quic_khsieh%40quicinc.com patch subject: [PATCH v1 02/14] drm/msm/dp: add dsc factor into calculation of supported bpp config: sparc-allyesconfig (https://download.01.org/0day-ci/archive/20230124/202301240748.rcxiazh1-...@intel.com/config) compiler: sparc64-linux-gcc (GCC) 12.1.0 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 # https://github.com/intel-lab-lkp/linux/commit/745d7acf9ef8affe996fce2f0658a6d95ac151fd git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Kuogee-Hsieh/drm-msm-dp-add-dpcd-read-of-both-dsc-and-fec-capability/20230124-022759 git checkout 745d7acf9ef8affe996fce2f0658a6d95ac151fd # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=sparc olddefconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=sparc SHELL=/bin/bash drivers/gpu/drm/msm/ If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot All warnings (new ones prefixed by >>): drivers/gpu/drm/msm/dp/dp_panel.c: In function 'dp_panel_get_supported_bpp': >> drivers/gpu/drm/msm/dp/dp_panel.c:125:34: warning: variable 'panel' set but >> not used [-Wunused-but-set-variable] 125 | struct dp_panel_private *panel; | ^ vim +/panel +125 drivers/gpu/drm/msm/dp/dp_panel.c 120 121 static u32 dp_panel_get_supported_bpp(struct dp_panel *dp_panel, 122 u32 mode_edid_bpp, u32 mode_pclk_khz) 123 { 124 struct dp_link_info *link_info; > 125 struct dp_panel_private *panel; 126 const u32 max_supported_bpp = 30; 127 u32 min_supported_bpp = 18; 128 u32 bpp = 0, link_bitrate = 0, mode_bitrate; 129 s64 rate_fp = 0; 130 131 panel = container_of(dp_panel, struct dp_panel_private, dp_panel); 132 133 if (dp_panel->dsc_en) 134 min_supported_bpp = 24; 135 136 bpp = min_t(u32, mode_edid_bpp, max_supported_bpp); 137 138 link_info = _panel->link_info; 139 140 rate_fp = drm_int2fixp(link_info->num_lanes * link_info->rate * 8); 141 142 if (dp_panel->fec_en) 143 rate_fp = drm_fixp_div(rate_fp, dp_panel->fec_overhead_fp); 144 145 link_bitrate = drm_fixp2int(rate_fp); 146 147 for (; bpp > min_supported_bpp; bpp -= 6) { 148 if (dp_panel->dsc_en) { 149 if (bpp == 30 && !(dp_panel->sink_dsc_caps.color_depth & DP_DSC_10_BPC)) 150 continue; 151 else if (bpp == 24 && !(dp_panel->sink_dsc_caps.color_depth & DP_DSC_8_BPC)) 152 continue; 153 154 mode_bitrate = mode_pclk_khz * DSC_TGT_BPP; 155 } else { 156 mode_bitrate = mode_pclk_khz * bpp; 157 } 158 159 if (mode_bitrate <= link_bitrate) 160 break; 161 } 162 163 if (bpp < min_supported_bpp) 164 DRM_ERROR("bpp %d is below minimum supported bpp %d\n", bpp, 165 min_supported_bpp); 166 167 if (dp_panel->dsc_en && bpp != 24 && bpp != 30 && bpp != 36) 168 DRM_ERROR("bpp %d is not supported when dsc is enabled\n", bpp); 169 170 return bpp; 171 } 172 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests
Re: [PATCH 1/8] drm/i915/guc: Add GuC oriented print macros
On 1/20/2023 08:40, Michal Wajdeczko wrote: While we do have GT oriented print macros, add few more GuC specific to have common look and feel across all messages related to the GuC and to avoid chasing the gt pointer. We will use these macros shortly in upcoming patches. Signed-off-by: Michal Wajdeczko Cc: Tvrtko Ursulin Cc: John Harrison --- drivers/gpu/drm/i915/gt/uc/intel_guc_print.h | 48 1 file changed, 48 insertions(+) create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_guc_print.h diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_print.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_print.h new file mode 100644 index ..e75989d4ba06 --- /dev/null +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_print.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2023 Intel Corporation + */ + +#ifndef __INTEL_GUC_PRINT__ +#define __INTEL_GUC_PRINT__ + +#include "gt/intel_gt.h" This necessary only for the guc_to_gt() accessor? Hmm. Maybe it is worth moving that to intel_guc.h? I know Jani for one would like to see all of that cleaned up. But maybe that's a follow up patch. John. +#include "gt/intel_gt_print.h" + +#define guc_printk(_guc, _level, _fmt, ...) \ + gt_##_level(guc_to_gt(_guc), "GUC: " _fmt, ##__VA_ARGS__) + +#define guc_err(_guc, _fmt, ...) \ + guc_printk((_guc), err, _fmt, ##__VA_ARGS__) + +#define guc_warn(_guc, _fmt, ...) \ + guc_printk((_guc), warn, _fmt, ##__VA_ARGS__) + +#define guc_notice(_guc, _fmt, ...) \ + guc_printk((_guc), notice, _fmt, ##__VA_ARGS__) + +#define guc_info(_guc, _fmt, ...) \ + guc_printk((_guc), info, _fmt, ##__VA_ARGS__) + +#define guc_dbg(_guc, _fmt, ...) \ + guc_printk((_guc), dbg, _fmt, ##__VA_ARGS__) + +#define guc_err_ratelimited(_guc, _fmt, ...) \ + guc_printk((_guc), err_ratelimited, _fmt, ##__VA_ARGS__) + +#define guc_probe_error(_guc, _fmt, ...) \ + guc_printk((_guc), probe_error, _fmt, ##__VA_ARGS__) + +#define guc_WARN(_guc, _cond, _fmt, ...) \ + gt_WARN(guc_to_gt(_guc), _cond, "GUC: " _fmt, ##__VA_ARGS__) + +#define guc_WARN_ONCE(_guc, _cond, _fmt, ...) \ + gt_WARN_ONCE(guc_to_gt(_guc), _cond, "GUC: " _fmt, ##__VA_ARGS__) + +#define guc_WARN_ON(_guc, _cond) \ + gt_WARN(guc_to_gt(_guc), _cond, "%s(%s)", "guc_WARN_ON", __stringify(_cond)) + +#define guc_WARN_ON_ONCE(_guc, _cond) \ + gt_WARN_ONCE(guc_to_gt(_guc), _cond, "%s(%s)", "guc_WARN_ON_ONCE", __stringify(_cond)) + +#endif /* __INTEL_GUC_PRINT__ */
Re: [PATCH drm-next 03/14] drm: manager to keep track of GPUs VA mappings
On Wed, Jan 18, 2023 at 07:12:45AM +0100, Danilo Krummrich wrote: This adds the infrastructure for a manager implementation to keep track of GPU virtual address (VA) mappings. New UAPIs, motivated by Vulkan sparse memory bindings graphics drivers start implementing, allow userspace applications to request multiple and arbitrary GPU VA mappings of buffer objects. The DRM GPU VA manager is intended to serve the following purposes in this context. 1) Provide a dedicated range allocator to track GPU VA allocations and mappings, making use of the drm_mm range allocator. 2) Generically connect GPU VA mappings to their backing buffers, in particular DRM GEM objects. 3) Provide a common implementation to perform more complex mapping operations on the GPU VA space. In particular splitting and merging of GPU VA mappings, e.g. for intersecting mapping requests or partial unmap requests. Idea-suggested-by: Dave Airlie Signed-off-by: Danilo Krummrich --- Documentation/gpu/drm-mm.rst| 31 + drivers/gpu/drm/Makefile|1 + drivers/gpu/drm/drm_gem.c |3 + drivers/gpu/drm/drm_gpuva_mgr.c | 1323 +++ include/drm/drm_drv.h |6 + include/drm/drm_gem.h | 75 ++ include/drm/drm_gpuva_mgr.h | 527 7 files changed, 1966 insertions(+) create mode 100644 drivers/gpu/drm/drm_gpuva_mgr.c create mode 100644 include/drm/drm_gpuva_mgr.h diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst index a52e6f4117d6..c9f120cfe730 100644 --- a/Documentation/gpu/drm-mm.rst +++ b/Documentation/gpu/drm-mm.rst @@ -466,6 +466,37 @@ DRM MM Range Allocator Function References .. kernel-doc:: drivers/gpu/drm/drm_mm.c :export: +DRM GPU VA Manager +== + +Overview + + +.. kernel-doc:: drivers/gpu/drm/drm_gpuva_mgr.c + :doc: Overview + +Split and Merge +--- + +.. kernel-doc:: drivers/gpu/drm/drm_gpuva_mgr.c + :doc: Split and Merge + +Locking +--- + +.. kernel-doc:: drivers/gpu/drm/drm_gpuva_mgr.c + :doc: Locking + + +DRM GPU VA Manager Function References +-- + +.. kernel-doc:: include/drm/drm_gpuva_mgr.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_gpuva_mgr.c + :export: + DRM Buddy Allocator === diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 4fe190aee584..de2ffca3b6e4 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -45,6 +45,7 @@ drm-y := \ drm_vblank.o \ drm_vblank_work.o \ drm_vma_manager.o \ + drm_gpuva_mgr.o \ drm_writeback.o drm-$(CONFIG_DRM_LEGACY) += \ drm_agpsupport.o \ diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 59a0bb5ebd85..65115fe88627 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -164,6 +164,9 @@ void drm_gem_private_object_init(struct drm_device *dev, if (!obj->resv) obj->resv = >_resv; + if (drm_core_check_feature(dev, DRIVER_GEM_GPUVA)) + drm_gem_gpuva_init(obj); + drm_vma_node_reset(>vma_node); INIT_LIST_HEAD(>lru_node); } diff --git a/drivers/gpu/drm/drm_gpuva_mgr.c b/drivers/gpu/drm/drm_gpuva_mgr.c new file mode 100644 index ..e665f642689d --- /dev/null +++ b/drivers/gpu/drm/drm_gpuva_mgr.c @@ -0,0 +1,1323 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 Red Hat. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Danilo Krummrich + * + */ + +#include +#include + +/** + * DOC: Overview + * + * The DRM GPU VA Manager, represented by struct drm_gpuva_manager keeps track + * of a GPU's virtual address (VA) space and manages the corresponding virtual + * mappings represented by _gpuva objects. It also keeps track of the + * mapping's backing _gem_object buffers. + * + * _gem_object buffers maintain a list (and
Re: [PATCH 8/8] drm/i915/guc: Update GT/GuC messages in intel_uc.c
On 1/20/2023 08:40, Michal Wajdeczko wrote: Use new macros to have common prefix that also include GT#. Signed-off-by: Michal Wajdeczko Cc: John Harrison --- drivers/gpu/drm/i915/gt/uc/intel_uc.c | 74 +-- 1 file changed, 36 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c index 9a8a1abf71d7..e94f0d7119c4 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c @@ -6,11 +6,13 @@ #include #include "gt/intel_gt.h" +#include "gt/intel_gt_print.h" #include "gt/intel_reset.h" #include "intel_gsc_fw.h" #include "intel_gsc_uc.h" #include "intel_guc.h" #include "intel_guc_ads.h" +#include "intel_guc_print.h" #include "intel_guc_submission.h" #include "gt/intel_rps.h" #include "intel_uc.h" @@ -67,14 +69,14 @@ static int __intel_uc_reset_hw(struct intel_uc *uc) ret = intel_reset_guc(gt); if (ret) { - DRM_ERROR("Failed to reset GuC, ret = %d\n", ret); + gt_err(gt, "Failed to reset GuC, ret = %d\n", ret); return ret; } guc_status = intel_uncore_read(gt->uncore, GUC_STATUS); - WARN(!(guc_status & GS_MIA_IN_RESET), -"GuC status: 0x%x, MIA core expected to be in reset\n", -guc_status); + gt_WARN(gt, !(guc_status & GS_MIA_IN_RESET), + "GuC status: 0x%x, MIA core expected to be in reset\n", + guc_status); return ret; } @@ -252,15 +254,13 @@ static int guc_enable_communication(struct intel_guc *guc) intel_guc_ct_event_handler(>ct); spin_unlock_irq(gt->irq_lock); - drm_dbg(>drm, "GuC communication enabled\n"); + guc_dbg(guc, "communication enabled\n"); return 0; } static void guc_disable_communication(struct intel_guc *guc) { - struct drm_i915_private *i915 = guc_to_gt(guc)->i915; - /* * Events generated during or after CT disable are logged by guc in * via mmio. Make sure the register is clear before disabling CT since @@ -280,11 +280,12 @@ static void guc_disable_communication(struct intel_guc *guc) */ guc_get_mmio_msg(guc); - drm_dbg(>drm, "GuC communication disabled\n"); + guc_dbg(guc, "communication disabled\n"); } static void __uc_fetch_firmwares(struct intel_uc *uc) { + struct intel_gt *gt = uc_to_gt(uc); int err; GEM_BUG_ON(!intel_uc_wants_guc(uc)); @@ -293,15 +294,13 @@ static void __uc_fetch_firmwares(struct intel_uc *uc) if (err) { /* Make sure we transition out of transient "SELECTED" state */ if (intel_uc_wants_huc(uc)) { - drm_dbg(_to_gt(uc)->i915->drm, - "Failed to fetch GuC: %d disabling HuC\n", err); + gt_dbg(gt, "Failed to fetch GuC fw (%pe) disabling HuC\n", ERR_PTR(err)); intel_uc_fw_change_status(>huc.fw, INTEL_UC_FIRMWARE_ERROR); } if (intel_uc_wants_gsc_uc(uc)) { - drm_dbg(_to_gt(uc)->i915->drm, - "Failed to fetch GuC: %d disabling GSC\n", err); + gt_dbg(gt, "Failed to fetch GuC fw (%pe) disabling GSC\n", ERR_PTR(err)); intel_uc_fw_change_status(>gsc.fw, INTEL_UC_FIRMWARE_ERROR); } @@ -382,7 +381,7 @@ static int uc_init_wopcm(struct intel_uc *uc) int err; if (unlikely(!base || !size)) { - i915_probe_error(gt->i915, "Unsuccessful WOPCM partitioning\n"); + gt_probe_error(gt, "Unsuccessful WOPCM partitioning\n"); return -E2BIG; } @@ -413,13 +412,13 @@ static int uc_init_wopcm(struct intel_uc *uc) return 0; err_out: - i915_probe_error(gt->i915, "Failed to init uC WOPCM registers!\n"); - i915_probe_error(gt->i915, "%s(%#x)=%#x\n", "DMA_GUC_WOPCM_OFFSET", -i915_mmio_reg_offset(DMA_GUC_WOPCM_OFFSET), -intel_uncore_read(uncore, DMA_GUC_WOPCM_OFFSET)); - i915_probe_error(gt->i915, "%s(%#x)=%#x\n", "GUC_WOPCM_SIZE", -i915_mmio_reg_offset(GUC_WOPCM_SIZE), -intel_uncore_read(uncore, GUC_WOPCM_SIZE)); + gt_probe_error(gt, "Failed to init uC WOPCM registers!\n"); + gt_probe_error(gt, "%s(%#x)=%#x\n", "DMA_GUC_WOPCM_OFFSET", + i915_mmio_reg_offset(DMA_GUC_WOPCM_OFFSET), + intel_uncore_read(uncore, DMA_GUC_WOPCM_OFFSET)); + gt_probe_error(gt, "%s(%#x)=%#x\n", "GUC_WOPCM_SIZE", + i915_mmio_reg_offset(GUC_WOPCM_SIZE), + intel_uncore_read(uncore, GUC_WOPCM_SIZE)); return err; } @@ -451,18 +450,17 @@
Re: [PATCH 7/8] drm/i915/guc: Update GuC messages in intel_guc_submission.c
On 1/20/2023 08:40, Michal Wajdeczko wrote: Use new macros to have common prefix that also include GT#. Signed-off-by: Michal Wajdeczko Cc: John Harrison --- .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 60 --- 1 file changed, 26 insertions(+), 34 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 b436dd7f12e4..bb98206304ee 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -27,6 +27,7 @@ #include "intel_guc_ads.h" #include "intel_guc_capture.h" +#include "intel_guc_print.h" #include "intel_guc_submission.h" #include "i915_drv.h" @@ -1443,8 +1444,7 @@ static void guc_init_engine_stats(struct intel_guc *guc) int ret = guc_action_enable_usage_stats(guc); if (ret) - drm_err(>i915->drm, - "Failed to enable usage stats: %d!\n", ret); + guc_err(guc, "Failed to enable usage stats: %pe\n", ERR_PTR(ret)); } } @@ -3585,8 +3585,7 @@ static int guc_request_alloc(struct i915_request *rq) intel_context_sched_disable_unpin(ce); else if (intel_context_is_closed(ce)) if (wait_for(context_close_done(ce), 1500)) - drm_warn(_to_gt(guc)->i915->drm, -"timed out waiting on context sched close before realloc\n"); + guc_warn(guc, "timed out waiting on context sched close before realloc\n"); /* * Call pin_guc_id here rather than in the pinning step as with * dma_resv, contexts can be repeatedly pinned / unpinned trashing the @@ -4349,11 +4348,14 @@ static int __guc_action_set_scheduling_policies(struct intel_guc *guc, ret = intel_guc_send(guc, (u32 *)>h2g, __guc_scheduling_policy_action_size(policy)); - if (ret < 0) + if (ret < 0) { + guc_probe_error(guc, "Failed to configure global scheduling policies: %pe!\n", + ERR_PTR(ret)); return ret; + } if (ret != policy->count) { - drm_warn(_to_gt(guc)->i915->drm, "GuC global scheduler policy processed %d of %d KLVs!", + guc_warn(guc, "global scheduler policy processed %d of %d KLVs!", ret, policy->count); if (ret > policy->count) return -EPROTO; @@ -4367,7 +4369,7 @@ static int guc_init_global_schedule_policy(struct intel_guc *guc) struct scheduling_policy policy; struct intel_gt *gt = guc_to_gt(guc); intel_wakeref_t wakeref; - int ret = 0; + int ret; if (GUC_SUBMIT_VER(guc) < MAKE_GUC_VER(1, 1, 0)) return 0; @@ -4385,10 +4387,6 @@ static int guc_init_global_schedule_policy(struct intel_guc *guc) yield, ARRAY_SIZE(yield)); ret = __guc_action_set_scheduling_policies(guc, ); - if (ret) - i915_probe_error(gt->i915, -"Failed to configure global scheduling policies: %pe!\n", -ERR_PTR(ret)); } return ret; @@ -4487,21 +4485,18 @@ g2h_context_lookup(struct intel_guc *guc, u32 ctx_id) struct intel_context *ce; if (unlikely(ctx_id >= GUC_MAX_CONTEXT_ID)) { - drm_err(_to_gt(guc)->i915->drm, - "Invalid ctx_id %u\n", ctx_id); + guc_err(guc, "Invalid ctx_id %u\n", ctx_id); return NULL; } ce = __get_context(guc, ctx_id); if (unlikely(!ce)) { - drm_err(_to_gt(guc)->i915->drm, - "Context is NULL, ctx_id %u\n", ctx_id); + guc_err(guc, "Context is NULL, ctx_id %u\n", ctx_id); return NULL; } if (unlikely(intel_context_is_child(ce))) { - drm_err(_to_gt(guc)->i915->drm, - "Context is child, ctx_id %u\n", ctx_id); + guc_err(guc, "Context is child, ctx_id %u\n", ctx_id); return NULL; } @@ -4516,7 +4511,7 @@ int intel_guc_deregister_done_process_msg(struct intel_guc *guc, u32 ctx_id; if (unlikely(len < 1)) { - drm_err(_to_gt(guc)->i915->drm, "Invalid length %u\n", len); + guc_err(guc, "Invalid length %u\n", len); return -EPROTO; } ctx_id = msg[0]; @@ -4568,7 +4563,7 @@ int intel_guc_sched_done_process_msg(struct intel_guc *guc, u32 ctx_id; if (unlikely(len < 2)) { - drm_err(_to_gt(guc)->i915->drm, "Invalid length %u\n", len); + guc_err(guc, "Invalid length %u\n", len); return -EPROTO; } ctx_id =
Re: [PATCH 6/8] drm/i915/guc: Update GuC messages in intel_guc_log.c
On 1/20/2023 08:40, Michal Wajdeczko wrote: Use new macros to have common prefix that also include GT#. Signed-off-by: Michal Wajdeczko Cc: John Harrison --- drivers/gpu/drm/i915/gt/uc/intel_guc_log.c | 35 +++--- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c index 68331c538b0a..1d76497b783c 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c @@ -12,6 +12,7 @@ #include "i915_memcpy.h" #include "intel_guc_capture.h" #include "intel_guc_log.h" +#include "intel_guc_print.h" #if defined(CONFIG_DRM_I915_DEBUG_GUC) #define GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE SZ_2M @@ -39,7 +40,6 @@ struct guc_log_section { static void _guc_log_init_sizes(struct intel_guc_log *log) { struct intel_guc *guc = log_to_guc(log); - struct drm_i915_private *i915 = guc_to_gt(guc)->i915; static const struct guc_log_section sections[GUC_LOG_SECTIONS_LIMIT] = { { GUC_LOG_CRASH_MASK >> GUC_LOG_CRASH_SHIFT, @@ -82,12 +82,12 @@ static void _guc_log_init_sizes(struct intel_guc_log *log) } if (!IS_ALIGNED(log->sizes[i].bytes, log->sizes[i].units)) - drm_err(>drm, "Mis-aligned GuC log %s size: 0x%X vs 0x%X!", + guc_err(guc, "Mis-aligned log %s size: 0x%X vs 0x%X!", sections[i].name, log->sizes[i].bytes, log->sizes[i].units); log->sizes[i].count = log->sizes[i].bytes / log->sizes[i].units; if (!log->sizes[i].count) { - drm_err(>drm, "Zero GuC log %s size!", sections[i].name); + guc_err(guc, "Zero log %s size!", sections[i].name); } else { /* Size is +1 unit */ log->sizes[i].count--; @@ -95,14 +95,14 @@ static void _guc_log_init_sizes(struct intel_guc_log *log) /* Clip to field size */ if (log->sizes[i].count > sections[i].max) { - drm_err(>drm, "GuC log %s size too large: %d vs %d!", + guc_err(guc, "log %s size too large: %d vs %d!", sections[i].name, log->sizes[i].count + 1, sections[i].max + 1); log->sizes[i].count = sections[i].max; } } if (log->sizes[GUC_LOG_SECTIONS_CRASH].units != log->sizes[GUC_LOG_SECTIONS_DEBUG].units) { - drm_err(>drm, "Unit mis-match for GuC log crash and debug sections: %d vs %d!", + guc_err(guc, "Unit mis-match for GuC log crash and debug sections: %d vs %d!", -> "for log, crash and debug sections" log->sizes[GUC_LOG_SECTIONS_CRASH].units, log->sizes[GUC_LOG_SECTIONS_DEBUG].units); log->sizes[GUC_LOG_SECTIONS_CRASH].units = log->sizes[GUC_LOG_SECTIONS_DEBUG].units; @@ -374,6 +374,7 @@ size_t intel_guc_get_log_buffer_offset(struct intel_guc_log *log, static void _guc_log_copy_debuglogs_for_relay(struct intel_guc_log *log) { + struct intel_guc *guc = log_to_guc(log); unsigned int buffer_size, read_offset, write_offset, bytes_to_copy, full_cnt; struct guc_log_buffer_state *log_buf_state, *log_buf_snapshot_state; struct guc_log_buffer_state log_buf_state_local; @@ -383,7 +384,7 @@ static void _guc_log_copy_debuglogs_for_relay(struct intel_guc_log *log) mutex_lock(>relay.lock); - if (WARN_ON(!intel_guc_log_relay_created(log))) + if (guc_WARN_ON(guc, !intel_guc_log_relay_created(log))) goto out_unlock; /* Get the pointer to shared GuC log buffer */ @@ -398,7 +399,7 @@ static void _guc_log_copy_debuglogs_for_relay(struct intel_guc_log *log) * Used rate limited to avoid deluge of messages, logs might be * getting consumed by User at a slow rate. */ - DRM_ERROR_RATELIMITED("no sub-buffer to copy general logs\n"); + guc_err_ratelimited(guc, "no sub-buffer to copy general logs\n"); log->relay.full_count++; goto out_unlock; @@ -451,7 +452,7 @@ static void _guc_log_copy_debuglogs_for_relay(struct intel_guc_log *log) write_offset = buffer_size; } else if (unlikely((read_offset > buffer_size) || (write_offset > buffer_size))) { - DRM_ERROR("invalid log buffer state\n"); + guc_err(guc, "invalid log buffer state\n"); /* copy whole buffer as offsets are unreliable */ read_offset = 0; write_offset = buffer_size; @@ -547,7 +548,7 @@ static int guc_log_relay_create(struct intel_guc_log *log)
Re: [PATCH 5/8] drm/i915/guc: Update GuC messages in intel_guc_fw.c
On 1/20/2023 08:40, Michal Wajdeczko wrote: Use new macros to have common prefix that also include GT#. Signed-off-by: Michal Wajdeczko Cc: John Harrison Reviewed-by: John Harrison --- drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c | 17 + 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c index 5b86b2e286e0..3d2249bda368 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c @@ -13,6 +13,7 @@ #include "gt/intel_gt_mcr.h" #include "gt/intel_gt_regs.h" #include "intel_guc_fw.h" +#include "intel_guc_print.h" #include "i915_drv.h" static void guc_prepare_xfer(struct intel_gt *gt) @@ -103,8 +104,10 @@ static inline bool guc_ready(struct intel_uncore *uncore, u32 *status) return uk_val == INTEL_GUC_LOAD_STATUS_READY; } -static int guc_wait_ucode(struct intel_uncore *uncore) +static int guc_wait_ucode(struct intel_guc *guc) { + struct intel_gt *gt = guc_to_gt(guc); + struct intel_uncore *uncore = gt->uncore; u32 status; int ret; @@ -127,10 +130,8 @@ static int guc_wait_ucode(struct intel_uncore *uncore) */ ret = wait_for(guc_ready(uncore, ), 200); if (ret) { - struct drm_device *drm = >i915->drm; - - drm_info(drm, "GuC load failed: status = 0x%08X\n", status); - drm_info(drm, "GuC load failed: status: Reset = %d, " + guc_info(guc, "load failed: status = 0x%08X\n", status); + guc_info(guc, "load failed: status: Reset = %d, " "BootROM = 0x%02X, UKernel = 0x%02X, " "MIA = 0x%02X, Auth = 0x%02X\n", REG_FIELD_GET(GS_MIA_IN_RESET, status), @@ -140,12 +141,12 @@ static int guc_wait_ucode(struct intel_uncore *uncore) REG_FIELD_GET(GS_AUTH_STATUS_MASK, status)); if ((status & GS_BOOTROM_MASK) == GS_BOOTROM_RSA_FAILED) { - drm_info(drm, "GuC firmware signature verification failed\n"); + guc_info(guc, "firmware signature verification failed\n"); ret = -ENOEXEC; } if (REG_FIELD_GET(GS_UKERNEL_MASK, status) == INTEL_GUC_LOAD_STATUS_EXCEPTION) { - drm_info(drm, "GuC firmware exception. EIP: %#x\n", + guc_info(guc, "firmware exception. EIP: %#x\n", intel_uncore_read(uncore, SOFT_SCRATCH(13))); ret = -ENXIO; } @@ -194,7 +195,7 @@ int intel_guc_fw_upload(struct intel_guc *guc) if (ret) goto out; - ret = guc_wait_ucode(uncore); + ret = guc_wait_ucode(guc); if (ret) goto out;
Re: [PATCH 4/8] drm/i915/guc: Update GuC messages in intel_guc_ct.c
On 1/20/2023 08:40, Michal Wajdeczko wrote: Use new macros to have common prefix that also include GT#. Signed-off-by: Michal Wajdeczko Cc: John Harrison --- drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 12 1 file changed, 4 insertions(+), 8 deletions(-) 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 2b22065e87bf..89adfc4193d2 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c @@ -11,6 +11,7 @@ #include "i915_drv.h" #include "intel_guc_ct.h" +#include "intel_guc_print.h" #include "gt/intel_gt.h" static inline struct intel_guc *ct_to_guc(struct intel_guc_ct *ct) @@ -28,21 +29,16 @@ static inline struct drm_i915_private *ct_to_i915(struct intel_guc_ct *ct) return ct_to_gt(ct)->i915; } -static inline struct drm_device *ct_to_drm(struct intel_guc_ct *ct) -{ - return _to_i915(ct)->drm; -} - #define CT_ERROR(_ct, _fmt, ...) \ - drm_err(ct_to_drm(_ct), "CT: " _fmt, ##__VA_ARGS__) + guc_err(ct_to_guc(_ct), "CT: " _fmt, ##__VA_ARGS__) #ifdef CONFIG_DRM_I915_DEBUG_GUC #define CT_DEBUG(_ct, _fmt, ...) \ - drm_dbg(ct_to_drm(_ct), "CT: " _fmt, ##__VA_ARGS__) + guc_dbg(ct_to_guc(_ct), "CT: " _fmt, ##__VA_ARGS__) #else #define CT_DEBUG(...) do { } while (0) #endif #define CT_PROBE_ERROR(_ct, _fmt, ...) \ - i915_probe_error(ct_to_i915(ct), "CT: " _fmt, ##__VA_ARGS__) + guc_probe_error(ct_to_guc(ct), "CT: " _fmt, ##__VA_ARGS__) ct_to_i915 is also now redundant and can be removed? John. /** * DOC: CTB Blob
Re: [PATCH 3/8] drm/i915/guc: Update GuC messages in intel_guc_ads.c
On 1/20/2023 08:40, Michal Wajdeczko wrote: Use new macros to have common prefix that also include GT#. Signed-off-by: Michal Wajdeczko Cc: John Harrison Reviewed-by: John Harrison --- drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c index a7f737c4792e..69ce06faf8cd 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c @@ -15,6 +15,7 @@ #include "intel_guc_ads.h" #include "intel_guc_capture.h" #include "intel_guc_fwif.h" +#include "intel_guc_print.h" #include "intel_uc.h" #include "i915_drv.h" @@ -427,7 +428,7 @@ static long guc_mmio_reg_state_create(struct intel_guc *guc) guc->ads_regset = temp_set.storage; - drm_dbg(_to_gt(guc)->i915->drm, "Used %zu KB for temporary ADS regset\n", + guc_dbg(guc, "Used %zu KB for temporary ADS regset\n", (temp_set.storage_max * sizeof(struct guc_mmio_reg)) >> 10); return total * sizeof(struct guc_mmio_reg); @@ -621,7 +622,7 @@ static void guc_init_golden_context(struct intel_guc *guc) engine = find_engine_state(gt, engine_class); if (!engine) { - drm_err(>i915->drm, "No engine state recorded for class %d!\n", + guc_err(guc, "No engine state recorded for class %d!\n", engine_class); ads_blob_write(guc, ads.eng_state_size[guc_class], 0); ads_blob_write(guc, ads.golden_context_lrca[guc_class], 0); @@ -646,7 +647,6 @@ static int guc_capture_prep_lists(struct intel_guc *guc) { struct intel_gt *gt = guc_to_gt(guc); - struct drm_i915_private *i915 = guc_to_gt(guc)->i915; u32 ads_ggtt, capture_offset, null_ggtt, total_size = 0; struct guc_gt_system_info local_info; struct iosys_map info_map; @@ -751,7 +751,7 @@ guc_capture_prep_lists(struct intel_guc *guc) } if (guc->ads_capture_size && guc->ads_capture_size != PAGE_ALIGN(total_size)) - drm_warn(>drm, "GuC->ADS->Capture alloc size changed from %d to %d\n", + guc_warn(guc, "ADS capture alloc size changed from %d to %d\n", guc->ads_capture_size, PAGE_ALIGN(total_size)); return PAGE_ALIGN(total_size);
[PATCH v3.1 4/7] drm: rcar-du: lvds: Fix stop sequence
From: Koji Matsuoka According to hardware manual, LVDCR0 register must be cleared bit by bit when disabling LVDS. Signed-off-by: Koji Matsuoka Signed-off-by: LUU HOAI [tomi.valkeinen: simplified the code a bit] Signed-off-by: Tomi Valkeinen Reviewed-by: Laurent Pinchart Signed-off-by: Laurent Pinchart --- Changes since v3: - Add comment explaining the register clear sequence --- drivers/gpu/drm/rcar-du/rcar_lvds.c | 31 + 1 file changed, 31 insertions(+) diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c index a11201e4d31b..260ea5d8624e 100644 --- a/drivers/gpu/drm/rcar-du/rcar_lvds.c +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c @@ -83,6 +83,11 @@ struct rcar_lvds { #define bridge_to_rcar_lvds(b) \ container_of(b, struct rcar_lvds, bridge) +static u32 rcar_lvds_read(struct rcar_lvds *lvds, u32 reg) +{ + return ioread32(lvds->mmio + reg); +} + static void rcar_lvds_write(struct rcar_lvds *lvds, u32 reg, u32 data) { iowrite32(data, lvds->mmio + reg); @@ -544,6 +549,32 @@ static void rcar_lvds_atomic_disable(struct drm_bridge *bridge, struct drm_bridge_state *old_bridge_state) { struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge); + u32 lvdcr0; + + /* +* Clear the LVDCR0 bits in the order specified by the hardware +* documentation, ending with a write of 0 to the full register to +* clear all remaining bits. +*/ + lvdcr0 = rcar_lvds_read(lvds, LVDCR0); + + lvdcr0 &= ~LVDCR0_LVRES; + rcar_lvds_write(lvds, LVDCR0, lvdcr0); + + if (lvds->info->quirks & RCAR_LVDS_QUIRK_GEN3_LVEN) { + lvdcr0 &= ~LVDCR0_LVEN; + rcar_lvds_write(lvds, LVDCR0, lvdcr0); + } + + if (lvds->info->quirks & RCAR_LVDS_QUIRK_PWD) { + lvdcr0 &= ~LVDCR0_PWD; + rcar_lvds_write(lvds, LVDCR0, lvdcr0); + } + + if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)) { + lvdcr0 &= ~LVDCR0_PLLON; + rcar_lvds_write(lvds, LVDCR0, lvdcr0); + } rcar_lvds_write(lvds, LVDCR0, 0); rcar_lvds_write(lvds, LVDCR1, 0); -- Regards, Laurent Pinchart
Re: [PATCH 2/8] drm/i915/guc: Update GuC messages in intel_guc.c
On 1/20/2023 08:40, Michal Wajdeczko wrote: Use new macros to have common prefix that also include GT#. Signed-off-by: Michal Wajdeczko Cc: John Harrison --- drivers/gpu/drm/i915/gt/uc/intel_guc.c | 31 +- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc.c index 1bccc175f9e6..be39e519b5fd 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c @@ -11,6 +11,7 @@ #include "intel_guc.h" #include "intel_guc_ads.h" #include "intel_guc_capture.h" +#include "intel_guc_print.h" #include "intel_guc_slpc.h" #include "intel_guc_submission.h" #include "i915_drv.h" @@ -94,8 +95,8 @@ static void gen9_enable_guc_interrupts(struct intel_guc *guc) assert_rpm_wakelock_held(>i915->runtime_pm); spin_lock_irq(gt->irq_lock); - WARN_ON_ONCE(intel_uncore_read(gt->uncore, GEN8_GT_IIR(2)) & -gt->pm_guc_events); + guc_WARN_ON_ONCE(guc, intel_uncore_read(gt->uncore, GEN8_GT_IIR(2)) & +gt->pm_guc_events); gen6_gt_pm_enable_irq(gt, gt->pm_guc_events); spin_unlock_irq(gt->irq_lock); @@ -342,7 +343,7 @@ static void guc_init_params(struct intel_guc *guc) params[GUC_CTL_DEVID] = guc_ctl_devid(guc); for (i = 0; i < GUC_CTL_MAX_DWORDS; i++) - DRM_DEBUG_DRIVER("param[%2d] = %#x\n", i, params[i]); + guc_dbg(guc, "param[%2d] = %#x\n", i, params[i]); } /* @@ -389,7 +390,6 @@ void intel_guc_dump_time_info(struct intel_guc *guc, struct drm_printer *p) int intel_guc_init(struct intel_guc *guc) { - struct intel_gt *gt = guc_to_gt(guc); int ret; ret = intel_uc_fw_init(>fw); @@ -451,7 +451,7 @@ int intel_guc_init(struct intel_guc *guc) intel_uc_fw_fini(>fw); out: intel_uc_fw_change_status(>fw, INTEL_UC_FIRMWARE_INIT_FAIL); - i915_probe_error(gt->i915, "failed with %d\n", ret); + guc_probe_error(guc, "failed with %pe\n", ERR_PTR(ret)); return ret; } @@ -480,7 +480,6 @@ void intel_guc_fini(struct intel_guc *guc) int intel_guc_send_mmio(struct intel_guc *guc, const u32 *request, u32 len, u32 *response_buf, u32 response_buf_size) { - struct drm_i915_private *i915 = guc_to_gt(guc)->i915; struct intel_uncore *uncore = guc_to_gt(guc)->uncore; u32 header; int i; @@ -515,7 +514,7 @@ int intel_guc_send_mmio(struct intel_guc *guc, const u32 *request, u32 len, 10, 10, ); if (unlikely(ret)) { timeout: - drm_err(>drm, "mmio request %#x: no reply %x\n", + guc_err(guc, "mmio request %#x: no reply %x\n", request[0], header); goto out; } @@ -537,7 +536,7 @@ int intel_guc_send_mmio(struct intel_guc *guc, const u32 *request, u32 len, if (FIELD_GET(GUC_HXG_MSG_0_TYPE, header) == GUC_HXG_TYPE_NO_RESPONSE_RETRY) { u32 reason = FIELD_GET(GUC_HXG_RETRY_MSG_0_REASON, header); - drm_dbg(>drm, "mmio request %#x: retrying, reason %u\n", + guc_dbg(guc, "mmio request %#x: retrying, reason %u\n", request[0], reason); goto retry; } @@ -546,7 +545,7 @@ int intel_guc_send_mmio(struct intel_guc *guc, const u32 *request, u32 len, u32 hint = FIELD_GET(GUC_HXG_FAILURE_MSG_0_HINT, header); u32 error = FIELD_GET(GUC_HXG_FAILURE_MSG_0_ERROR, header); - drm_err(>drm, "mmio request %#x: failure %x/%u\n", + guc_err(guc, "mmio request %#x: failure %x/%u\n", request[0], error, hint); ret = -ENXIO; goto out; @@ -554,7 +553,7 @@ int intel_guc_send_mmio(struct intel_guc *guc, const u32 *request, u32 len, if (FIELD_GET(GUC_HXG_MSG_0_TYPE, header) != GUC_HXG_TYPE_RESPONSE_SUCCESS) { proto: - drm_err(>drm, "mmio request %#x: unexpected reply %#x\n", + guc_err(guc, "mmio request %#x: unexpected reply %#x\n", request[0], header); ret = -EPROTO; goto out; @@ -597,9 +596,9 @@ int intel_guc_to_host_process_recv_msg(struct intel_guc *guc, msg = payload[0] & guc->msg_enabled_mask; if (msg & INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED) - drm_err(_to_gt(guc)->i915->drm, "Received early GuC crash dump notification!\n"); + guc_err(guc, "Received early GuC crash dump notification!\n"); if (msg & INTEL_GUC_RECV_MSG_EXCEPTION) - drm_err(_to_gt(guc)->i915->drm, "Received early GuC exception notification!\n"); + guc_err(guc, "Received early GuC exception notification!\n"); These two should drop the 'GUC' string from the message given that it is now a prefix. John. return 0;
Re: [Lsf-pc] [LSF/MM/BPF proposal]: Physr discussion
On Mon, Jan 23, 2023 at 12:50:52PM -0800, Dan Williams wrote: > Matthew Wilcox wrote: > > On Mon, Jan 23, 2023 at 11:36:51AM -0800, Dan Williams wrote: > > > Jason Gunthorpe via Lsf-pc wrote: > > > > I would like to have a session at LSF to talk about Matthew's > > > > physr discussion starter: > > > > > > > > https://lore.kernel.org/linux-mm/ydykweu0htv8m...@casper.infradead.org/ > > > > > > > > I have become interested in this with some immediacy because of > > > > IOMMUFD and this other discussion with Christoph: > > > > > > > > > > > > https://lore.kernel.org/kvm/4-v2-472615b3877e+28f7-vfio_dma_buf_...@nvidia.com/ > > > > > > I think this is a worthwhile discussion. My main hangup with 'struct > > > page' elimination in general is that if anything needs to be allocated > > > > You're the first one to bring up struct page elimination. Neither Jason > > nor I have that as our motivation. > > Oh, ok, then maybe I misread the concern in the vfio discussion. I > thought the summary there is debating the ongoing requirement for > 'struct page' for P2PDMA? My reading of that thread is that while it started out that way, it became more about "So what would a good interface be for doing this". And Jason's right, he and I are approaching this from different directions. My concern is from the GUP side where we start out by getting a folio (which we know is physically contiguous) and decomposing it into pages. Then we aggregate all those pages together which are physically contiguous and stuff them into a bio_vec. After that, I lose interest; I was planning on having DMA mapping interfaces which took in an array of phyr and spat out scatterlists. Then we could shrink the scatterlist by removing page_link and offset, leaving us with only dma_address, length and maybe flags.
Re: [PATCH v1 06/14] drm/msm/dp: add display compression related struct
On 23/01/2023 20:24, Kuogee Hsieh wrote: Add display compression related struct to support variant compression mechanism. However, DSC is the only one supported at this moment. VDC may be added later. Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/dp/dp_panel.h | 42 ++ drivers/gpu/drm/msm/msm_drv.h | 89 +++ 2 files changed, 131 insertions(+) diff --git a/drivers/gpu/drm/msm/dp/dp_panel.h b/drivers/gpu/drm/msm/dp/dp_panel.h index 1153e88..4c45d51 100644 --- a/drivers/gpu/drm/msm/dp/dp_panel.h +++ b/drivers/gpu/drm/msm/dp/dp_panel.h @@ -21,12 +21,54 @@ struct edid; #define DP_DOWNSTREAM_PORTS 4 #define DP_DOWNSTREAM_CAP_SIZE4 + +#define DP_PANEL_CAPS_DSC BIT(0) + +enum dp_output_format { + DP_OUTPUT_FORMAT_RGB, + DP_OUTPUT_FORMAT_YCBCR420, + DP_OUTPUT_FORMAT_YCBCR422, + DP_OUTPUT_FORMAT_YCBCR444, + DP_OUTPUT_FORMAT_INVALID, +}; + + +struct dp_panel_info { + u32 h_active; + u32 v_active; + u32 h_back_porch; + u32 h_front_porch; + u32 h_sync_width; + u32 h_active_low; + u32 v_back_porch; + u32 v_front_porch; + u32 v_sync_width; + u32 v_active_low; + u32 h_skew; + u32 refresh_rate; + u32 pixel_clk_khz; + u32 bpp; + bool widebus_en; + struct msm_compression_info comp_info; + s64 dsc_overhead_fp; +}; + struct dp_display_mode { struct drm_display_mode drm_mode; + struct dp_panel_info timing; u32 capabilities; + s64 fec_overhead_fp; + s64 dsc_overhead_fp; u32 bpp; u32 h_active_low; u32 v_active_low; + /** +* @output_format: +* +* This is used to indicate DP output format. +* The output format can be read from drm_mode. +*/ + enum dp_output_format output_format; }; struct dp_panel_in { diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 9f0c184..f155803 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2023. Qualcomm Innovation Center, Inc. All rights reserved * Copyright (C) 2013 Red Hat * Author: Rob Clark */ @@ -70,6 +71,16 @@ enum msm_dp_controller { #define MAX_H_TILES_PER_DISPLAY 2 /** + * enum msm_display_compression_type - compression method used for pixel stream + * @MSM_DISPLAY_COMPRESSION_NONE: Pixel data is not compressed + * @MSM_DISPLAY_COMPRESSION_DSC: DSC compresison is used + */ +enum msm_display_compression_type { + MSM_DISPLAY_COMPRESSION_NONE, + MSM_DISPLAY_COMPRESSION_DSC, +}; + +/** * enum msm_event_wait - type of HW events to wait for * @MSM_ENC_COMMIT_DONE - wait for the driver to flush the registers to HW * @MSM_ENC_TX_COMPLETE - wait for the HW to transfer the frame to panel @@ -82,6 +93,84 @@ enum msm_event_wait { }; /** + * struct msm_display_dsc_info - defines dsc configuration This structure was removed. Please keep it this way. We are not going to reintroduce it unless it is really required for some reason. And up to now I don't see a good reason for adding it back. + * @config DSC encoder configuration + * @scr_rev: DSC revision. + * @initial_lines: Number of initial lines stored in encoder. + * @pkt_per_line:Number of packets per line. + * @bytes_in_slice: Number of bytes in slice. + * @eol_byte_num:Valid bytes at the end of line. + * @bytes_per_pktNumber of bytes in DSI packet + * @pclk_per_line: Compressed width. + * @slice_last_group_size: Size of last group in pixels. + * @slice_per_pkt: Number of slices per packet. + * @num_active_ss_per_enc: Number of active soft slices per encoder. + * @source_color_space: Source color space of DSC encoder + * @chroma_format: Chroma_format of DSC encoder. + * @det_thresh_flatness: Flatness threshold. + * @extra_width: Extra width required in timing calculations. + * @pps_delay_ms:Post PPS command delay in milliseconds. + * @dsc_4hsmerge_en: Using DSC 4HS merge topology + * @dsc_4hsmerge_padding 4HS merge DSC pair padding value in bytes + * @dsc_4hsmerge_alignment 4HS merge DSC alignment value in bytes + * @half_panel_puTrue for single and dual dsc encoders if partial + * update sets the roi width to half of mode width + * False in all other cases + */ +struct msm_display_dsc_info { + struct drm_dsc_config drm_dsc; + u8 scr_rev; + + int initial_lines; + int pkt_per_line; + int bytes_in_slice; + int bytes_per_pkt; + int eol_byte_num; +
Re: [ANNOUNCE] pixfmtdb
On Monday, January 23rd, 2023 at 21:25, Sebastian Wick wrote: > Why is the TF defined for GL formats and both the primaries and TF for > Vulkan formats? The only exception here should be sRGB formats. Where > did you get the information from? This is what upstream dfdutils does [1]. Can you explain why you think it should be undefined instead of linear? I was wondering what to do for DRM formats regarding these. I think it would be worthwhile to do like Vulkan: set TF = linear, primaries = BT.709, pre-multiplied alpha = yes. These are the things KMS assume when there is no override (ie, when there is no KMS property saying otherwise). [1]: https://github.com/KhronosGroup/dfdutils/blob/5cd41cbdf63e80b00c085c6906a1152709e4c0f2/createdfd.c#L47
Re: [PATCH v2 1/1] Docs/subsystem-apis: Remove '[The ]Linux' prefixes from titles of listed documents
On Sun, 2023-01-22 at 18:48 +, SeongJae Park wrote: > Some documents that listed on subsystem-apis have 'Linux' or 'The Linux' > title prefixes. It's duplicated information, and makes finding the > document of interest with human eyes not easy. Remove the prefixes from > the titles. > > Signed-off-by: SeongJae Park For Documentation/peci/index.rst Acked-by: Iwona Winiarska > --- > Changes from v1 > (https://lore.kernel.org/lkml/20230114194741.115855-1...@kernel.org/) > - Drop second patch (will post later for each subsystem) > > Documentation/PCI/index.rst | 6 +++--- > Documentation/cpu-freq/index.rst | 6 +++--- > Documentation/crypto/index.rst | 6 +++--- > Documentation/driver-api/index.rst | 6 +++--- > Documentation/gpu/index.rst | 6 +++--- > Documentation/hwmon/index.rst | 6 +++--- > Documentation/input/index.rst | 6 +++--- > Documentation/mm/index.rst | 6 +++--- > Documentation/peci/index.rst | 6 +++--- > Documentation/scheduler/index.rst | 6 +++--- > Documentation/scsi/index.rst | 6 +++--- > Documentation/sound/index.rst | 6 +++--- > Documentation/virt/index.rst | 6 +++--- > Documentation/watchdog/index.rst | 6 +++--- > 14 files changed, 42 insertions(+), 42 deletions(-)
Re: [PATCH v1 04/14] drm/msm/dp: correct configure Colorimetry Indicator Field at MISC0
On 23/01/2023 20:24, Kuogee Hsieh wrote: MSA MISC0 bit 1 to 7 contains Colorimetry Indicator Field. At current implementation, Colorimetry Indicator Field of MISC0 is not configured correctly. This patch add support of RGB formats Colorimetry. Any Fixes tag? Not to mention that fixes should come first. Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/dp/dp_ctrl.c | 5 +++-- drivers/gpu/drm/msm/dp/dp_link.c | 29 +++-- drivers/gpu/drm/msm/dp/dp_panel.c | 45 +++ drivers/gpu/drm/msm/dp/dp_panel.h | 1 + 4 files changed, 71 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c index 959a78c..d0d1848 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2023, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved */ #define pr_fmt(fmt) "[drm-dp] %s: " fmt, __func__ @@ -169,7 +170,7 @@ static void dp_ctrl_configure_source_params(struct dp_ctrl_private *ctrl) tb = dp_link_get_test_bits_depth(ctrl->link, ctrl->panel->dp_mode.bpp); - cc = dp_link_get_colorimetry_config(ctrl->link); + cc = dp_panel_get_misc_colorimetry_val(ctrl->panel); dp_catalog_ctrl_config_misc(ctrl->catalog, cc, tb); dp_panel_timing_cfg(ctrl->panel); } diff --git a/drivers/gpu/drm/msm/dp/dp_link.c b/drivers/gpu/drm/msm/dp/dp_link.c index f1f1d64..e957948 100644 --- a/drivers/gpu/drm/msm/dp/dp_link.c +++ b/drivers/gpu/drm/msm/dp/dp_link.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2023, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved */ #define pr_fmt(fmt) "[drm-dp] %s: " fmt, __func__ @@ -12,6 +13,12 @@ #define DP_TEST_REQUEST_MASK 0x7F +enum dynamic_range { + DP_DYNAMIC_RANGE_RGB_VESA = 0x00, + DP_DYNAMIC_RANGE_RGB_CEA = 0x01, + DP_DYNAMIC_RANGE_UNKNOWN = 0x, No need to assign values here, unless they serve some purpose. Do they? +}; + enum audio_sample_rate { AUDIO_SAMPLE_RATE_32_KHZ= 0x00, AUDIO_SAMPLE_RATE_44_1_KHZ = 0x01, @@ -1079,6 +1086,7 @@ int dp_link_process_request(struct dp_link *dp_link) int dp_link_get_colorimetry_config(struct dp_link *dp_link) { u32 cc; + enum dynamic_range dr; struct dp_link_private *link; if (!dp_link) { @@ -1088,14 +1096,21 @@ int dp_link_get_colorimetry_config(struct dp_link *dp_link) link = container_of(dp_link, struct dp_link_private, dp_link); - /* -* Unless a video pattern CTS test is ongoing, use RGB_VESA -* Only RGB_VESA and RGB_CEA supported for now -*/ + /* unless a video pattern CTS test is ongoing, use CEA_VESA */ if (dp_link_is_video_pattern_requested(link)) - cc = link->dp_link.test_video.test_dyn_range; + dr = link->dp_link.test_video.test_dyn_range; else - cc = DP_TEST_DYNAMIC_RANGE_VESA; + dr = DP_DYNAMIC_RANGE_RGB_VESA; + + /* Only RGB_VESA nd RGB_CEA supported for now */ + switch (dr) { + case DP_DYNAMIC_RANGE_RGB_CEA: + cc = BIT(2); + break; + case DP_DYNAMIC_RANGE_RGB_VESA: + default: + cc = 0; + } return cc; } diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c index 36dad05..55bb6b0 100644 --- a/drivers/gpu/drm/msm/dp/dp_panel.c +++ b/drivers/gpu/drm/msm/dp/dp_panel.c @@ -567,6 +567,51 @@ int dp_panel_init_panel_info(struct dp_panel *dp_panel) return 0; } +/** This marks the start of kerneldoc. But the rest of the comment isn't a kerneldoc. + * Mapper function which outputs colorimetry to be used for a + * given colorspace value when misc field of MSA is used to + * change the colorimetry. Currently only RGB formats have been + * added. This API will be extended to YUV once its supported on DP. its != it's + */ +u8 dp_panel_get_misc_colorimetry_val(struct dp_panel *dp_panel) +{ + u8 colorimetry; + u32 colorspace; + u32 cc; + struct dp_panel_private *panel; + + panel = container_of(dp_panel, struct dp_panel_private, dp_panel); + + cc = dp_link_get_colorimetry_config(panel->link); + /* +* If there is a non-zero value then compliance test-case +* is going on, otherwise we can honor the colorspace setting +*/ + if (cc) + return cc; + + colorspace = dp_panel->connector->state->colorspace; + switch
Re: [PATCH v3 4/7] drm: rcar-du: lvds: Fix stop sequence
Hi Geert, On Mon, Jan 23, 2023 at 03:28:08PM +0100, Geert Uytterhoeven wrote: > On Mon, Jan 23, 2023 at 11:48 AM Tomi Valkeinen wrote: > > From: Koji Matsuoka > > > > According to hardware manual, LVDCR0 register must be cleared bit by bit > > when disabling LVDS. > > > > Signed-off-by: Koji Matsuoka > > Signed-off-by: LUU HOAI > > [tomi.valkeinen: simplified the code a bit] > > Signed-off-by: Tomi Valkeinen > > Reviewed-by: Laurent Pinchart > > Thanks for your patch! > > > @@ -544,6 +549,27 @@ static void rcar_lvds_atomic_disable(struct drm_bridge > > *bridge, > > struct drm_bridge_state > > *old_bridge_state) > > { > > struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge); > > + u32 lvdcr0; > > + > > + lvdcr0 = rcar_lvds_read(lvds, LVDCR0); > > + > > + lvdcr0 &= ~LVDCR0_LVRES; > > + rcar_lvds_write(lvds, LVDCR0, lvdcr0); > > + > > + if (lvds->info->quirks & RCAR_LVDS_QUIRK_GEN3_LVEN) { > > + lvdcr0 &= ~LVDCR0_LVEN; > > + rcar_lvds_write(lvds, LVDCR0, lvdcr0); > > + } > > + > > + if (lvds->info->quirks & RCAR_LVDS_QUIRK_PWD) { > > + lvdcr0 &= ~LVDCR0_PWD; > > + rcar_lvds_write(lvds, LVDCR0, lvdcr0); > > + } > > + > > + if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)) { > > + lvdcr0 &= ~LVDCR0_PLLON; > > + rcar_lvds_write(lvds, LVDCR0, lvdcr0); > > + } > > Please add a comment explaining why there are multiple register writes, > to avoid an over-zealous janitor "optimizing" the code later. I'll add this comment at the top of the function: /* * Clear the LVDCR0 bits in the order specified by the hardware * documentation, ending with a write of 0 to the full register to * clear all remaining bits. */ > > > > rcar_lvds_write(lvds, LVDCR0, 0); > > rcar_lvds_write(lvds, LVDCR1, 0); -- Regards, Laurent Pinchart
Re: [PATCH v1 03/14] drm/msm/dp: add configure mainlink_levels base on lane number
On 23/01/2023 20:24, Kuogee Hsieh wrote: Mainlink_levels determined when two actions to take place by hardware, a new BS sequence due to start of video and a static HW MVID is sent to panel. This patch add function to configure mainlink level properly base on lane number. Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/dp/dp_catalog.c | 37 - drivers/gpu/drm/msm/dp/dp_catalog.h | 4 +++- drivers/gpu/drm/msm/dp/dp_ctrl.c| 4 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c index 676279d..7ac37d8 100644 --- a/drivers/gpu/drm/msm/dp/dp_catalog.c +++ b/drivers/gpu/drm/msm/dp/dp_catalog.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2023, The Linux Foundation. All rights reserved. + * Copyright (c) 2021. Qualcomm Innovation Center, Inc. All rights reserved */ #define pr_fmt(fmt) "[drm-dp] %s: " fmt, __func__ @@ -359,6 +360,40 @@ void dp_catalog_ctrl_lane_mapping(struct dp_catalog *dp_catalog) ln_mapping); } +void dp_catalog_ctrl_mainlink_levels(struct dp_catalog *dp_catalog, + u8 lane_cnt) +{ + struct dp_catalog_private *catalog = container_of(dp_catalog, + struct dp_catalog_private, dp_catalog); + + u32 mainlink_levels, safe_to_exit_level = 14; + + switch (lane_cnt) { + case 1: + safe_to_exit_level = 14; + break; + case 2: + safe_to_exit_level = 8; + break; + case 4: + safe_to_exit_level = 5; + break; + default: + drm_dbg_dp(catalog->drm_dev, "setting the default safe_to_exit_level=%u\n", + safe_to_exit_level); So, set it here rather than somewhere at the top of the function. + break; + } + + mainlink_levels = dp_read_link(catalog, REG_DP_MAINLINK_LEVELS); + mainlink_levels &= 0xFE0; + mainlink_levels |= safe_to_exit_level; + + drm_dbg_dp(catalog->drm_dev, "mainlink_level=0x%x, safe_to_exit_level=0x%x\n", + mainlink_levels, safe_to_exit_level); + + dp_write_link(catalog, REG_DP_MAINLINK_LEVELS, mainlink_levels); +} + void dp_catalog_ctrl_mainlink_ctrl(struct dp_catalog *dp_catalog, bool enable) { diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h index 1f717f4..990c162 100644 --- a/drivers/gpu/drm/msm/dp/dp_catalog.h +++ b/drivers/gpu/drm/msm/dp/dp_catalog.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2023, The Linux Foundation. All rights reserved. + * Copyright (c) 2021. Qualcomm Innovation Center, Inc. All rights reserved */ #ifndef _DP_CATALOG_H_ @@ -92,6 +93,7 @@ u32 dp_catalog_aux_get_irq(struct dp_catalog *dp_catalog); void dp_catalog_ctrl_state_ctrl(struct dp_catalog *dp_catalog, u32 state); void dp_catalog_ctrl_config_ctrl(struct dp_catalog *dp_catalog, u32 config); void dp_catalog_ctrl_lane_mapping(struct dp_catalog *dp_catalog); +void dp_catalog_ctrl_mainlink_levels(struct dp_catalog *dp_catalog, u8 lane_cnt); void dp_catalog_ctrl_mainlink_ctrl(struct dp_catalog *dp_catalog, bool enable); void dp_catalog_ctrl_config_misc(struct dp_catalog *dp_catalog, u32 cc, u32 tb); void dp_catalog_ctrl_config_msa(struct dp_catalog *dp_catalog, u32 rate, diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c index dd26ca6..959a78c 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -161,6 +161,8 @@ static void dp_ctrl_configure_source_params(struct dp_ctrl_private *ctrl) u32 cc, tb; dp_catalog_ctrl_lane_mapping(ctrl->catalog); + dp_catalog_ctrl_mainlink_levels(ctrl->catalog, + ctrl->link->link_params.num_lanes); dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, true); dp_ctrl_config_ctrl(ctrl); @@ -1296,6 +1298,8 @@ static int dp_ctrl_setup_main_link(struct dp_ctrl_private *ctrl, { int ret = 0; + dp_catalog_ctrl_mainlink_levels(ctrl->catalog, + ctrl->link->link_params.num_lanes); dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, true); if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) -- With best wishes Dmitry
Re: [PATCH v1 08/14] drm/msm/dp: add dsc supporting functions to DP controller
On 23/01/2023 20:24, Kuogee Hsieh wrote: This patch provides DSC required functions at DP controller to complete DSC feature. those functions include enable fec, configure dsc, configure dto, transmit pps and finally flush hardware registers. Too many items for a single patch in my opinion. Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/dp/dp_catalog.c | 139 - drivers/gpu/drm/msm/dp/dp_catalog.h | 93 ++ drivers/gpu/drm/msm/dp/dp_ctrl.c| 132 - drivers/gpu/drm/msm/dp/dp_display.c | 61 +++- drivers/gpu/drm/msm/dp/dp_panel.c | 570 +++- drivers/gpu/drm/msm/dp/dp_panel.h | 4 + drivers/gpu/drm/msm/dp/dp_reg.h | 40 ++- drivers/gpu/drm/msm/msm_drv.h | 16 + 8 files changed, 1033 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c index 7ac37d8..20a86e7 100644 --- a/drivers/gpu/drm/msm/dp/dp_catalog.c +++ b/drivers/gpu/drm/msm/dp/dp_catalog.c @@ -48,6 +48,11 @@ #define DP_INTERRUPT_STATUS2_MASK \ (DP_INTERRUPT_STATUS2 << DP_INTERRUPT_STATUS_MASK_SHIFT) +enum dp_flush_bit { + DP_PPS_FLUSH, + DP_DHDR_FLUSH, +}; + struct dp_catalog_private { struct device *dev; struct drm_device *drm_dev; @@ -277,6 +282,30 @@ static void dump_regs(void __iomem *base, int len) } } +void dp_catalog_fec_config(struct dp_catalog *dp_catalog, bool enable) +{ + struct dp_catalog_private *catalog = container_of(dp_catalog, + struct dp_catalog_private, dp_catalog); + u32 reg; + + reg = dp_read_link(catalog, REG_DP_MAINLINK_CTRL); + + /* +* fec_en = BIT(12) +* fec_seq_mode = BIT(22) +* sde_flush = BIT(23) | BIT(24) +* fb_boundary_sel = BIT(25) This should go to #define's instead. +*/ + if (enable) + reg |= BIT(12) | BIT(22) | BIT(23) | BIT(24) | BIT(25); + else + reg &= ~BIT(12); + + dp_write_link(catalog, REG_DP_MAINLINK_CTRL, reg); + /* make sure mainlink configuration is updated with fec sequence */ + wmb(); +} + void dp_catalog_dump_regs(struct dp_catalog *dp_catalog) { struct dp_catalog_private *catalog = container_of(dp_catalog, @@ -344,6 +373,54 @@ void dp_catalog_ctrl_config_ctrl(struct dp_catalog *dp_catalog, u32 cfg) dp_write_link(catalog, REG_DP_CONFIGURATION_CTRL, cfg); } +void dp_catalog_config_dsc_dto(struct dp_catalog *dp_catalog) +{ + struct dp_catalog_private *catalog = container_of(dp_catalog, + struct dp_catalog_private, dp_catalog); + struct dp_dsc_cfg_data *dsc_data = _catalog->dsc_data; + u32 reg; + + dp_write_p0(catalog, MMSS_DP_DSC_DTO_COUNT, dsc_data->dto_count); + + reg = dp_read_p0(catalog, MMSS_DP_DSC_DTO); + + if (dsc_data->dto_en) { + reg |= BIT(0); + reg |= BIT(3); + reg |= (dsc_data->dto_n << 8); + reg |= (dsc_data->dto_d << 16); + } + + dp_write_p0(catalog, MMSS_DP_DSC_DTO, reg); + + reg = 0; + if (dsc_data->dsc_en) { + reg = BIT(0); + reg |= (dsc_data->eol_byte_num << 3); + reg |= (dsc_data->slice_per_pkt << 5); + reg |= (dsc_data->bytes_per_pkt << 16); + reg |= (dsc_data->be_in_lane << 10); + } + dp_write_link(catalog, DP_COMPRESSION_MODE_CTRL, reg); + + drm_dbg_dp(catalog->drm_dev, "compression:0x%x\n", reg); +} + +void dp_catalog_override_ack_dto(struct dp_catalog *dp_catalog, bool not_ack) +{ + struct dp_catalog_private *catalog = container_of(dp_catalog, + struct dp_catalog_private, dp_catalog); +u32 dsc_dto; + + dsc_dto = dp_read_p0(catalog, MMSS_DP_DSC_DTO); +if (not_ack) +dsc_dto &= ~BIT(1); +else +dsc_dto = BIT(1); + + dp_write_p0(catalog, MMSS_DP_DSC_DTO, dsc_dto); The indentation looks weird. It might be my email client. Or may be not. +} + void dp_catalog_ctrl_lane_mapping(struct dp_catalog *dp_catalog) { struct dp_catalog_private *catalog = container_of(dp_catalog, @@ -429,6 +506,15 @@ void dp_catalog_ctrl_mainlink_ctrl(struct dp_catalog *dp_catalog, } } +static void dp_catalog_sdp_update( struct dp_catalog *dp_catalog) +{ + struct dp_catalog_private *catalog = container_of(dp_catalog, + struct dp_catalog_private, dp_catalog); + + dp_write_link(catalog, MMSS_DP_SDP_CFG3, 0x01); + dp_write_link(catalog, MMSS_DP_SDP_CFG3, 0x00); +} + void dp_catalog_ctrl_config_misc(struct dp_catalog *dp_catalog, u32 colorimetry_cfg, u32 test_bits_depth) @@ -504,7 +590,6 @@ void dp_catalog_ctrl_config_msa(struct dp_catalog
Re: [PATCH v1 01/14] drm/msm/dp: add dpcd read of both dsc and fec capability
On 23/01/2023 20:24, Kuogee Hsieh wrote: FEC is pre-requirement of DSC. Therefore FEC has to be enabled before DSC enabled. This patch add functions to read sink's DSC and FEC related DPCD and decode them and set enable flags accordingly. Please split this to FEC and DSC patches. Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/dp/dp_panel.c | 91 ++- drivers/gpu/drm/msm/dp/dp_panel.h | 20 - 2 files changed, 109 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c index 1800d89..5078247 100644 --- a/drivers/gpu/drm/msm/dp/dp_panel.c +++ b/drivers/gpu/drm/msm/dp/dp_panel.c @@ -1,14 +1,18 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2023, The Linux Foundation. All rights reserved. + * Copyright (c) 2023. Qualcomm Innovation Center, Inc. All rights reserved */ #include "dp_panel.h" +#include #include #include #include +#define DSC_TGT_BPP 8 + struct dp_panel_private { struct device *dev; struct drm_device *drm_dev; @@ -68,6 +72,9 @@ static int dp_panel_read_dpcd(struct dp_panel *dp_panel) goto end; } + print_hex_dump_debug("[drm-dp] SINK DPCD: ", + DUMP_PREFIX_NONE, 8, 1, dp_panel->dpcd, rlen, false); I think this can go away. + link_info->revision = dpcd[DP_DPCD_REV]; major = (link_info->revision >> 4) & 0x0f; minor = link_info->revision & 0x0f; @@ -154,6 +161,83 @@ static int dp_panel_update_modes(struct drm_connector *connector, return rc; } +static void dp_panel_decode_dsc_dpcd(struct dp_panel *dp_panel) +{ + if (dp_panel->dsc_dpcd[0]) { + dp_panel->sink_dsc_caps.dsc_capable = true; + dp_panel->sink_dsc_caps.version = dp_panel->dsc_dpcd[1]; + dp_panel->sink_dsc_caps.block_pred_en = + dp_panel->dsc_dpcd[6] ? true : false; + dp_panel->sink_dsc_caps.color_depth = + dp_panel->dsc_dpcd[10]; + + if (dp_panel->sink_dsc_caps.version >= 0x11) + dp_panel->dsc_en = true; + } else { + dp_panel->sink_dsc_caps.dsc_capable = false; + dp_panel->dsc_en = false; + } +} + +static void dp_panel_read_sink_dsc_caps(struct dp_panel *dp_panel) +{ + int rlen; + struct dp_panel_private *panel; + int dpcd_rev; + + if (!dp_panel) { + DRM_ERROR("invalid input\n"); + return; + } + + dpcd_rev = dp_panel->dpcd[DP_DPCD_REV]; + + panel = container_of(dp_panel, struct dp_panel_private, dp_panel); + if (dpcd_rev >= 0x14) { + rlen = drm_dp_dpcd_read(panel->aux, DP_DSC_SUPPORT, + dp_panel->dsc_dpcd, (DP_DSC_RECEIVER_CAP_SIZE + 1)); + if (rlen < (DP_DSC_RECEIVER_CAP_SIZE + 1)) { + drm_dbg_dp(panel->drm_dev, "dsc dpcd read failed, rlen=%d\n", rlen); + return; + } + + print_hex_dump_debug("[drm-dp] SINK DSC DPCD: ", + DUMP_PREFIX_NONE, 8, 1, dp_panel->dsc_dpcd, rlen, false); Oh. An extra dump again. Can we get rid of them please? Or can we use the standard drm debug levels? So that it would be possible to turn them on and off with standard params. + + dp_panel_decode_dsc_dpcd(dp_panel); + } +} + +static void dp_panel_read_sink_fec_caps(struct dp_panel *dp_panel) +{ + int rlen; + struct dp_panel_private *panel; + s64 fec_overhead_fp = drm_fixp_from_fraction(1, 1); + + if (!dp_panel) { + DRM_ERROR("invalid input\n"); + return; + } + + panel = container_of(dp_panel, struct dp_panel_private, dp_panel); + rlen = drm_dp_dpcd_readb(panel->aux, DP_FEC_CAPABILITY, + _panel->fec_dpcd); + if (rlen < 1) { + DRM_ERROR("fec capability read failed, rlen=%d\n", rlen); + return; + } + + print_hex_dump_debug("[drm-dp] SINK FEC DPCD: ", + DUMP_PREFIX_NONE, 8, 1, _panel->fec_dpcd, rlen, false); + + dp_panel->fec_en = dp_panel->fec_dpcd & DP_FEC_CAPABLE; + + if (dp_panel->fec_en) + fec_overhead_fp = drm_fixp_from_fraction(10, 97582); + + dp_panel->fec_overhead_fp = fec_overhead_fp; +} + int dp_panel_read_sink_caps(struct dp_panel *dp_panel, struct drm_connector *connector) { @@ -224,6 +308,11 @@ int dp_panel_read_sink_caps(struct dp_panel *dp_panel, } panel->aux_cfg_update_done = false; } + + dp_panel_read_sink_fec_caps(dp_panel); + + if (dp_panel->fec_en) + dp_panel_read_sink_dsc_caps(dp_panel); end: return
Re: [PATCH v1 07/14] drm/msm/dp: add dsc helper functions
This has nothing to do with /dp, make it /dpu On 2023-01-23 10:24:27, Kuogee Hsieh wrote: > Add DSC related supporting functions to calculate DSC related parameters. > In addition, DSC hardware encoder customized configuration parameters are > also included. Algorithms used to perform calculation are derived from > system engineer spreadsheet. > > Signed-off-by: Kuogee Hsieh > --- > drivers/gpu/drm/msm/Makefile | 1 + > drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.c | 537 > + > drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.h | 25 ++ > drivers/gpu/drm/msm/msm_drv.h | 4 + > 4 files changed, 567 insertions(+) > create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.c > create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.h > > diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile > index 7274c412..28cf52b 100644 > --- a/drivers/gpu/drm/msm/Makefile > +++ b/drivers/gpu/drm/msm/Makefile > @@ -65,6 +65,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \ > disp/dpu1/dpu_hw_catalog.o \ > disp/dpu1/dpu_hw_ctl.o \ > disp/dpu1/dpu_hw_dsc.o \ > + disp/dpu1/dpu_dsc_helper.o \ > disp/dpu1/dpu_hw_interrupts.o \ > disp/dpu1/dpu_hw_intf.o \ > disp/dpu1/dpu_hw_lm.o \ > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.c > new file mode 100644 > index ..48cef23 > --- /dev/null > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.c > @@ -0,0 +1,537 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Copyright (c) 2012-2023 The Linux Foundation. All rights reserved. > + * Copyright (c) 2023. Qualcomm Innovation Center, Inc. All rights reserved > + */ > + > +#include "msm_drv.h" > +#include "dpu_kms.h" > +#include "dpu_hw_dsc.h" > +#include "dpu_dsc_helper.h" > + > + > +#define DPU_DSC_PPS_SIZE 128 > + > +enum dpu_dsc_ratio_type { > + DSC_V11_8BPC_8BPP, > + DSC_V11_10BPC_8BPP, > + DSC_V11_10BPC_10BPP, > + DSC_V11_SCR1_8BPC_8BPP, > + DSC_V11_SCR1_10BPC_8BPP, > + DSC_V11_SCR1_10BPC_10BPP, > + DSC_V12_444_8BPC_8BPP = DSC_V11_SCR1_8BPC_8BPP, > + DSC_V12_444_10BPC_8BPP = DSC_V11_SCR1_10BPC_8BPP, > + DSC_V12_444_10BPC_10BPP = DSC_V11_SCR1_10BPC_10BPP, > + DSC_V12_422_8BPC_7BPP, > + DSC_V12_422_8BPC_8BPP, > + DSC_V12_422_10BPC_7BPP, > + DSC_V12_422_10BPC_10BPP, > + DSC_V12_420_8BPC_6BPP, > + DSC_V12_420_10BPC_6BPP, > + DSC_V12_420_10BPC_7_5BPP, > + DSC_RATIO_TYPE_MAX > +}; > + > + > +static u16 dpu_dsc_rc_buf_thresh[DSC_NUM_BUF_RANGES - 1] = { > + 0x0e, 0x1c, 0x2a, 0x38, 0x46, 0x54, > + 0x62, 0x69, 0x70, 0x77, 0x79, 0x7b, 0x7d, 0x7e > +}; > + > +/* > + * Rate control - Min QP values for each ratio type in dpu_dsc_ratio_type > + */ > +static char dpu_dsc_rc_range_min_qp[DSC_RATIO_TYPE_MAX][DSC_NUM_BUF_RANGES] > = { > + /* DSC v1.1 */ > + {0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 13}, > + {0, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 17}, > + {0, 4, 5, 6, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 15}, > + /* DSC v1.1 SCR and DSC v1.2 RGB 444 */ > + {0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 9, 12}, > + {0, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 13, 16}, > + {0, 4, 5, 6, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 15}, > + /* DSC v1.2 YUV422 */ > + {0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 11}, > + {0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10}, > + {0, 4, 5, 6, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 15}, > + {0, 2, 3, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 11, 12}, > + /* DSC v1.2 YUV420 */ > + {0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10}, > + {0, 2, 3, 4, 6, 7, 7, 7, 7, 7, 9, 9, 9, 11, 14}, > + {0, 2, 3, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 11, 12}, > +}; > + > +/* > + * Rate control - Max QP values for each ratio type in dpu_dsc_ratio_type > + */ > +static char dpu_dsc_rc_range_max_qp[DSC_RATIO_TYPE_MAX][DSC_NUM_BUF_RANGES] > = { > + /* DSC v1.1 */ > + {4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 11, 12, 13, 13, 15}, > + {4, 8, 9, 10, 11, 11, 11, 12, 13, 14, 15, 16, 17, 17, 19}, > + {7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16}, > + /* DSC v1.1 SCR and DSC v1.2 RGB 444 */ > + {4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 12, 13}, > + {8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 16, 17}, > + {7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16}, > + /* DSC v1.2 YUV422 */ > + {3, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12}, > + {2, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 10, 11}, > + {7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16}, > + {2, 5, 5, 6, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13}, > + /* DSC v1.2 YUV420 */ > + {2, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 10, 12}, > + {2, 5, 7, 8, 9, 10, 11, 12, 12, 13, 13, 13, 13, 14, 15}, > + {2, 5, 5, 6, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13}, > + }; > + > +/* > + * Rate control - bpg offset
Re: [PATCH v1 09/14] drm/msm/dsi: export struct msm_compression_info to dpu encoder
On 23/01/2023 20:24, Kuogee Hsieh wrote: struct msm_compression_info is used to support several different compression mechanisms. It also contains customized info required to configure DSC encoder engine. This patch also make changes DSI module to have DSI exports struct msm_compreion_info to dpu encoder instead of struct drm_dsc_config. Let's see how patch 07 evolves first. But generally I don't like the idea of passing around another wrapper structure. Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 7 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 4 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 10 -- drivers/gpu/drm/msm/dsi/dsi.c | 3 ++- drivers/gpu/drm/msm/dsi/dsi.h | 3 ++- drivers/gpu/drm/msm/dsi/dsi_host.c | 14 -- drivers/gpu/drm/msm/msm_drv.h | 4 ++-- 7 files changed, 33 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 758261e..7f4a439 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -2,7 +2,7 @@ /* * Copyright (C) 2013 Red Hat * Copyright (c) 2014-2018, 2020-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. * * Author: Rob Clark */ @@ -210,6 +210,7 @@ struct dpu_encoder_virt { /* DSC configuration */ struct drm_dsc_config *dsc; + struct msm_compression_info *comp_info; }; #define to_dpu_encoder_virt(x) container_of(x, struct dpu_encoder_virt, base) @@ -2275,7 +2276,9 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, dpu_enc->idle_pc_supported = dpu_kms->catalog->caps->has_idle_pc; - dpu_enc->dsc = disp_info->dsc; + dpu_enc->comp_info = disp_info->comp_info; + if (dpu_enc->comp_info) + dpu_enc->dsc = _enc->comp_info->msm_dsc_info.drm_dsc; mutex_lock(_enc->enc_lock); for (i = 0; i < disp_info->num_of_h_tiles && !ret; i++) { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h index 9e7236e..bd2da5e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -36,7 +36,7 @@ struct msm_display_info { uint32_t h_tile_instance[MAX_H_TILES_PER_DISPLAY]; bool is_cmd_mode; bool is_te_using_watchdog_timer; - struct drm_dsc_config *dsc; + struct msm_compression_info *comp_info; }; /** diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index d612419..70a74ed 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -2,7 +2,7 @@ /* * Copyright (C) 2013 Red Hat * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. * * Author: Rob Clark */ @@ -570,7 +570,7 @@ static int _dpu_kms_initialize_dsi(struct drm_device *dev, info.h_tile_instance[info.num_of_h_tiles++] = i; info.is_cmd_mode = msm_dsi_is_cmd_mode(priv->dsi[i]); - info.dsc = msm_dsi_get_dsc_config(priv->dsi[i]); + info.comp_info = msm_dsi_get_dsc_config(priv->dsi[i]); if (msm_dsi_is_bonded_dsi(priv->dsi[i]) && priv->dsi[other]) { rc = msm_dsi_modeset_init(priv->dsi[other], dev, encoder); @@ -622,6 +622,8 @@ static int _dpu_kms_initialize_displayport(struct drm_device *dev, info.num_of_h_tiles = 1; info.h_tile_instance[0] = i; info.intf_type = encoder->encoder_type; + info.is_cmd_mode = 0; /* dp always video mode */ + info.comp_info = NULL; rc = dpu_encoder_setup(dev, encoder, ); if (rc) { DPU_ERROR("failed to setup DPU encoder %d: rc:%d\n", @@ -892,6 +894,10 @@ static void dpu_kms_mdp_snapshot(struct msm_disp_state *disp_state, struct msm_k pm_runtime_get_sync(_kms->pdev->dev); + for (i = 0; i < cat->dsc_count; i++) + msm_disp_snapshot_add_block(disp_state, cat->dsc[i].len, + dpu_kms->mmio + cat->dsc[i].base,
Re: [PATCH v1 07/14] drm/msm/dp: add dsc helper functions
On 23/01/2023 20:24, Kuogee Hsieh wrote: Add DSC related supporting functions to calculate DSC related parameters. In addition, DSC hardware encoder customized configuration parameters are also included. Algorithms used to perform calculation are derived from system engineer spreadsheet. Overall impression. First rewrite this patch to use existing data structures and helpers. Then move the remnants to the drm/display/drm_dsc_helper.c. Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.c | 537 + drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.h | 25 ++ drivers/gpu/drm/msm/msm_drv.h | 4 + 4 files changed, 567 insertions(+) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.h diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 7274c412..28cf52b 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -65,6 +65,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \ disp/dpu1/dpu_hw_catalog.o \ disp/dpu1/dpu_hw_ctl.o \ disp/dpu1/dpu_hw_dsc.o \ + disp/dpu1/dpu_dsc_helper.o \ disp/dpu1/dpu_hw_interrupts.o \ disp/dpu1/dpu_hw_intf.o \ disp/dpu1/dpu_hw_lm.o \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.c new file mode 100644 index ..48cef23 --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.c @@ -0,0 +1,537 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2012-2023 The Linux Foundation. All rights reserved. + * Copyright (c) 2023. Qualcomm Innovation Center, Inc. All rights reserved + */ + +#include "msm_drv.h" +#include "dpu_kms.h" +#include "dpu_hw_dsc.h" +#include "dpu_dsc_helper.h" + + +#define DPU_DSC_PPS_SIZE 128 doesn't sizeof(drm_dsc_picture_parameter_set) work instead? + +enum dpu_dsc_ratio_type { + DSC_V11_8BPC_8BPP, + DSC_V11_10BPC_8BPP, + DSC_V11_10BPC_10BPP, + DSC_V11_SCR1_8BPC_8BPP, + DSC_V11_SCR1_10BPC_8BPP, + DSC_V11_SCR1_10BPC_10BPP, + DSC_V12_444_8BPC_8BPP = DSC_V11_SCR1_8BPC_8BPP, + DSC_V12_444_10BPC_8BPP = DSC_V11_SCR1_10BPC_8BPP, + DSC_V12_444_10BPC_10BPP = DSC_V11_SCR1_10BPC_10BPP, + DSC_V12_422_8BPC_7BPP, + DSC_V12_422_8BPC_8BPP, + DSC_V12_422_10BPC_7BPP, + DSC_V12_422_10BPC_10BPP, + DSC_V12_420_8BPC_6BPP, + DSC_V12_420_10BPC_6BPP, + DSC_V12_420_10BPC_7_5BPP, + DSC_RATIO_TYPE_MAX +}; + + +static u16 dpu_dsc_rc_buf_thresh[DSC_NUM_BUF_RANGES - 1] = { + 0x0e, 0x1c, 0x2a, 0x38, 0x46, 0x54, + 0x62, 0x69, 0x70, 0x77, 0x79, 0x7b, 0x7d, 0x7e +}; + +/* + * Rate control - Min QP values for each ratio type in dpu_dsc_ratio_type + */ +static char dpu_dsc_rc_range_min_qp[DSC_RATIO_TYPE_MAX][DSC_NUM_BUF_RANGES] = { + /* DSC v1.1 */ + {0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 13}, + {0, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 17}, + {0, 4, 5, 6, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 15}, + /* DSC v1.1 SCR and DSC v1.2 RGB 444 */ + {0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 9, 12}, + {0, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 13, 16}, + {0, 4, 5, 6, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 15}, + /* DSC v1.2 YUV422 */ + {0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 11}, + {0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10}, + {0, 4, 5, 6, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 15}, + {0, 2, 3, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 11, 12}, + /* DSC v1.2 YUV420 */ + {0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10}, + {0, 2, 3, 4, 6, 7, 7, 7, 7, 7, 9, 9, 9, 11, 14}, + {0, 2, 3, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 11, 12}, +}; + +/* + * Rate control - Max QP values for each ratio type in dpu_dsc_ratio_type + */ +static char dpu_dsc_rc_range_max_qp[DSC_RATIO_TYPE_MAX][DSC_NUM_BUF_RANGES] = { + /* DSC v1.1 */ + {4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 11, 12, 13, 13, 15}, + {4, 8, 9, 10, 11, 11, 11, 12, 13, 14, 15, 16, 17, 17, 19}, + {7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16}, + /* DSC v1.1 SCR and DSC v1.2 RGB 444 */ + {4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 12, 13}, + {8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 16, 17}, + {7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16}, + /* DSC v1.2 YUV422 */ + {3, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12}, + {2, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 10, 11}, + {7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16}, + {2, 5, 5, 6, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13}, + /* DSC v1.2 YUV420 */ + {2, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 10, 12}, + {2, 5, 7, 8, 9, 10, 11, 12, 12, 13, 13, 13, 13, 14, 15}, + {2, 5, 5, 6, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13},
Re: [PATCH v1 11/14] drm/msm/disp/dpu1: add supports of new flush mechanism
On 23/01/2023 20:24, Kuogee Hsieh wrote: A new flushing mechanism is introduced to decouple peripheral metadata flushing from timing engine related flush. This patch add peripheral flushing functions. Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 24 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 2 + .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 7 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 43 -- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 21 +++ 5 files changed, 91 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 901e317..d2625b3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1472,6 +1472,12 @@ static void _dpu_encoder_trigger_flush(struct drm_encoder *drm_enc, if (extra_flush_bits && ctl->ops.update_pending_flush) ctl->ops.update_pending_flush(ctl, extra_flush_bits); + if (phys->hw_intf->cap->type == INTF_DP && + phys->comp_type == MSM_DISPLAY_COMPRESSION_DSC && + phys->comp_ratio) { Do you really need to know comp_ratio here? And the comp_type? + ctl->ops.update_pending_flush_periph(ctl, phys->hw_intf->idx); + } + ctl->ops.trigger_flush(ctl); if (ctl->ops.get_pending_flush) @@ -1814,12 +1820,18 @@ dpu_encoder_dsc_initial_line_calc(struct drm_dsc_config *dsc, return DIV_ROUND_UP(total_pixels, dsc->slice_width); } -static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc, +static void dpu_encoder_dsc_pipe_cfg(struct dpu_encoder_virt *dpu_enc, +struct dpu_hw_dsc *hw_dsc, struct dpu_hw_pingpong *hw_pp, struct drm_dsc_config *dsc, u32 common_mode, u32 initial_lines) { + struct dpu_encoder_phys *cur_master = dpu_enc->cur_master; + struct dpu_hw_ctl *ctl; + + ctl = cur_master->hw_ctl; + if (hw_dsc->ops.dsc_config) hw_dsc->ops.dsc_config(hw_dsc, dsc, common_mode, initial_lines, false); @@ -1834,6 +1846,10 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc, if (hw_pp->ops.enable_dsc) hw_pp->ops.enable_dsc(hw_pp); + + if (ctl->ops.update_pending_flush_dsc) + ctl->ops.update_pending_flush_dsc(ctl, hw_dsc->idx); + } static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc, @@ -1877,8 +1893,10 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc, enc_ip_w = intf_ip_w / 2; initial_lines = dpu_encoder_dsc_initial_line_calc(dsc, enc_ip_w); - for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) - dpu_encoder_dsc_pipe_cfg(hw_dsc[i], hw_pp[i], dsc, dsc_common_mode, initial_lines); + for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { + dpu_encoder_dsc_pipe_cfg(dpu_enc, hw_dsc[i], hw_pp[i], dsc, + dsc_common_mode, initial_lines); + } } void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h index 1d434b2..0569b36 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -200,6 +200,8 @@ struct dpu_encoder_phys { atomic_t pending_kickoff_cnt; wait_queue_head_t pending_kickoff_wq; int irq[INTR_IDX_MAX]; + enum msm_display_compression_type comp_type; + u32 comp_ratio; }; static inline int dpu_encoder_phys_inc_pending(struct dpu_encoder_phys *phys) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c index 48c4810..2d864f9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2015-2018, 2020-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. */ #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ @@ -427,6 +428,12 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc) if (ctl->ops.update_pending_flush_merge_3d && phys_enc->hw_pp->merge_3d) ctl->ops.update_pending_flush_merge_3d(ctl, phys_enc->hw_pp->merge_3d->idx); + if (phys_enc->hw_intf->cap->type == INTF_DP && + phys_enc->comp_type == MSM_DISPLAY_COMPRESSION_DSC && + phys_enc->comp_ratio) { +
Re: [PATCH v1 12/14] drm/msm/disp/dpu1: revise timing engine programming to work for DSC
On 23/01/2023 20:24, Kuogee Hsieh wrote: Current implementation timing engine programming does not consider compression factors. This patch add consideration of DSC factors while programming timing engine. Signed-off-by: Kuogee Hsieh --- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 2 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 14 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c| 132 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h| 10 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h | 6 +- 5 files changed, 110 insertions(+), 54 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c index 2d864f9..3330e185 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c @@ -279,6 +279,8 @@ static void dpu_encoder_phys_vid_setup_timing_engine( if (phys_enc->hw_pp->merge_3d) intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx; + phys_enc->hw_intf->hw_rev = phys_enc->dpu_kms->core_rev; + spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); phys_enc->hw_intf->ops.setup_timing_gen(phys_enc->hw_intf, _params, fmt); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 7b0b092..c6ee789 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -43,16 +43,22 @@ #define DPU_HW_VER_500DPU_HW_VER(5, 0, 0) /* sm8150 v1.0 */ #define DPU_HW_VER_501DPU_HW_VER(5, 0, 1) /* sm8150 v2.0 */ #define DPU_HW_VER_510DPU_HW_VER(5, 1, 1) /* sc8180 */ -#define DPU_HW_VER_600 DPU_HW_VER(6, 0, 0) /* sm8250 */ +#define DPU_HW_VER_600 DPU_HW_VER(6, 0, 0) /* sm8250, kona */ #define DPU_HW_VER_620DPU_HW_VER(6, 2, 0) /* sc7180 v1.0 */ #define DPU_HW_VER_630DPU_HW_VER(6, 3, 0) /* sm6115|sm4250 */ #define DPU_HW_VER_650DPU_HW_VER(6, 5, 0) /* qcm2290|sm4125 */ -#define DPU_HW_VER_700 DPU_HW_VER(7, 0, 0) /* sm8350 */ +#define DPU_HW_VER_700 DPU_HW_VER(7, 0, 0) /* sm8350, lahaina */ #define DPU_HW_VER_720DPU_HW_VER(7, 2, 0) /* sc7280 */ #define DPU_HW_VER_800DPU_HW_VER(8, 0, 0) /* sc8280xp */ -#define DPU_HW_VER_810 DPU_HW_VER(8, 1, 0) /* sm8450 */ +#define DPU_HW_VER_810 DPU_HW_VER(8, 1, 0) /* sm8450, waipio */ #define DPU_HW_VER_900DPU_HW_VER(9, 0, 0) /* sm8550 */ No. +/* Avoid using below IS_XXX macros outside catalog, use feature bit instead */ +#define IS_DPU_MAJOR_SAME(rev1, rev2) \ + (DPU_HW_MAJOR((rev1)) == DPU_HW_MAJOR((rev2))) +#define IS_DPU_MAJOR_MINOR_SAME(rev1, rev2) \ + (DPU_HW_MAJOR_MINOR((rev1)) == DPU_HW_MAJOR_MINOR((rev2))) + #define IS_MSM8996_TARGET(rev) IS_DPU_MAJOR_MINOR_SAME((rev), DPU_HW_VER_170) #define IS_MSM8998_TARGET(rev) IS_DPU_MAJOR_MINOR_SAME((rev), DPU_HW_VER_300) #define IS_SDM845_TARGET(rev) IS_DPU_MAJOR_MINOR_SAME((rev), DPU_HW_VER_400) @@ -240,6 +246,7 @@ enum { * @DPU_INTF_INPUT_CTRL Supports the setting of pp block from which * pixel data arrives to this INTF * @DPU_INTF_TE INTF block has TE configuration support + * @DPU_INTF_TE_ALIGN_VSYNC INTF block has POMS Align vsync support * @DPU_DATA_HCTL_ENAllows data to be transferred at different rate than video timing * @DPU_INTF_MAX @@ -247,6 +254,7 @@ enum { enum { DPU_INTF_INPUT_CTRL = 0x1, DPU_INTF_TE, + DPU_INTF_TE_ALIGN_VSYNC, DPU_DATA_HCTL_EN, DPU_INTF_MAX }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c index 7ce66bf..238efdb 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ @@ -44,6 +44,7 @@ #define INTF_DEFLICKER_STRNG_COEFF0x0F4 #define INTF_DEFLICKER_WEAK_COEFF 0x0F8 +#define INTF_REG_SPLIT_LINK 0x080 #define INTF_DSI_CMD_MODE_TRIGGER_EN 0x084 #define INTF_PANEL_FORMAT 0x090 #define INTF_TPG_ENABLE 0x100 @@ -65,9 +66,9 @@ #define INTF_CFG_ACTIVE_H_EN BIT(29) #define INTF_CFG_ACTIVE_V_EN BIT(30) - #define INTF_CFG2_DATABUS_WIDEN BIT(0) #define INTF_CFG2_DATA_HCTL_ENBIT(4) +#define INTF_CFG2_ALIGN_VSYNC_TO_TE BIT(16) #define INTF_MISR_CTRL 0x180 #define INTF_MISR_SIGNATURE 0x184 @@ -91,6 +92,16 @@ static const struct dpu_intf_cfg
Re: [PATCH 2/6] dt-bindings: phy: qcom,hdmi-phy-other: mark it as clock provider
On Thu, 19 Jan 2023 15:22:15 +0200, Dmitry Baryshkov wrote: > Eventually all HDMI PHYs are going to provide the HDMI PLL clock to the > MMCC. Add #clock-cells property required to provide the HDMI PLL clock to > other devices. > > Signed-off-by: Dmitry Baryshkov > --- > .../devicetree/bindings/phy/qcom,hdmi-phy-other.yaml | 4 > 1 file changed, 4 insertions(+) > Acked-by: Rob Herring
Re: [PATCH] dt-bindings: drop type for operating-points-v2
On Thu, 19 Jan 2023 14:10:33 +0100, Krzysztof Kozlowski wrote: > The type for operating-points-v2 property is coming from dtschema > (/schemas/opp/opp.yaml), so individual bindings can just use simple > "true". > > Signed-off-by: Krzysztof Kozlowski > > --- > > This depends on my pull request, at least logically: > https://github.com/devicetree-org/dt-schema/pull/95 > > Patch could be applied in parallel but only if above PULL is > accepted/correct. > --- > .../devicetree/bindings/display/msm/dp-controller.yaml | 3 +-- > .../devicetree/bindings/display/tegra/nvidia,tegra20-dc.yaml | 3 +-- > .../devicetree/bindings/display/tegra/nvidia,tegra20-dsi.yaml | 3 +-- > .../devicetree/bindings/display/tegra/nvidia,tegra20-epp.yaml | 3 +-- > .../devicetree/bindings/display/tegra/nvidia,tegra20-gr2d.yaml | 3 +-- > .../devicetree/bindings/display/tegra/nvidia,tegra20-gr3d.yaml | 3 +-- > .../devicetree/bindings/display/tegra/nvidia,tegra20-hdmi.yaml | 3 +-- > .../bindings/display/tegra/nvidia,tegra20-host1x.yaml | 3 +-- > .../devicetree/bindings/display/tegra/nvidia,tegra20-mpe.yaml | 3 +-- > .../devicetree/bindings/display/tegra/nvidia,tegra20-tvo.yaml | 3 +-- > .../devicetree/bindings/display/tegra/nvidia,tegra20-vi.yaml | 3 +-- > .../devicetree/bindings/fuse/nvidia,tegra20-fuse.yaml | 3 +-- > .../devicetree/bindings/mmc/nvidia,tegra20-sdhci.yaml | 3 +-- > Documentation/devicetree/bindings/power/power-domain.yaml | 3 --- > Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.yaml | 3 +-- > 15 files changed, 14 insertions(+), 31 deletions(-) > Applied, thanks!
Re: [PATCH v2 7/9] drm/i915/pxp: MTL-KCR interrupt ctrl's are in GT-0
On Wed, 2023-01-18 at 18:01 -0800, Ceraolo Spurio, Daniele wrote: > > > On 1/11/2023 1:42 PM, Alan Previn wrote: > > Despite KCR subsystem being in the media-tile (close to the > > GSC-CS), the IRQ controls for it are on GT-0 with other global > > IRQ controls. Thus, add a helper for KCR hw interrupt > > enable/disable functions to get the correct gt structure (for > > uncore) for MTL. > > > > In the helper, we get GT-0's handle for uncore when touching > > IRQ registers despite the pxp->ctrl_gt being the media-tile. > > No difference for legacy of course. > > > > Signed-off-by: Alan Previn > > --- > > drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c | 2 +- > > drivers/gpu/drm/i915/pxp/intel_pxp_irq.c | 23 +--- > > drivers/gpu/drm/i915/pxp/intel_pxp_irq.h | 8 +++ > > 3 files changed, 29 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c > > b/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c > > index 4b8e70caa3ad..9f6e300486b4 100644 > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c > > @@ -44,7 +44,7 @@ static int pxp_terminate_get(void *data, u64 *val) > > static int pxp_terminate_set(void *data, u64 val) > > { > > struct intel_pxp *pxp = data; > > - struct intel_gt *gt = pxp->ctrl_gt; > > + struct intel_gt *gt = intel_pxp_get_irq_gt(pxp); > > This doesn't seem to be required here. The only use of gt in this > function is an assert below and both the root and media gt point to the > same irq_lock, so it doesn't matter which one we're using. Should we > keep it anyway just for safety in case things change in the future? or > just add a comment instead? > I rather we keep this helper for consistency: everything else in front-end pxp code is using pxp->ctrl_gt, but if we use pxp->[root_gt] here, it would just read like a bug without understanding the hw details. As you have pointed out farther down, the helper could just return root gt always (since they both point to the same IRQ register). I will go ahead and follow your recommendation for the helper internals (with the comments explaining in detail) but have the callers continue to use that helper. > > > > if (!intel_pxp_is_active(pxp)) > > return -ENODEV; > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c > > b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c > > index 91e9622c07d0..2eef0c19e91a 100644 > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c > > @@ -8,6 +8,7 @@ > > #include "gt/intel_gt_regs.h" > > #include "gt/intel_gt_types.h" > > > > +#include "i915_drv.h" > > #include "i915_irq.h" > > #include "i915_reg.h" > > > > @@ -17,6 +18,22 @@ > > #include "intel_pxp_types.h" > > #include "intel_runtime_pm.h" > > > > +/** > > + * intel_pxp_get_irq_gt - Find the correct GT that owns KCR interrupts > > + * @pxp: pointer to pxp struct > > + * > > + * For platforms with a single GT, we return the pxp->ctrl_gt (as expected) > > + * but for MTL+ that has a media-tile, although the KCR engine is in the > > + * media-tile (i.e. pxp->ctrl_gt), the IRQ controls are on the root tile. > > + */ > > +struct intel_gt *intel_pxp_get_irq_gt(struct intel_pxp *pxp) > > +{ > > + if (pxp->uses_gsccs) > > + return to_gt(pxp->ctrl_gt->i915); > > + > > + return pxp->ctrl_gt; > > AFAICT here we can skip the if and always return the root gt, because > that's what happens in both cases. If you want to make sure we don't get > issues in the future maybe instead add a: > > GEM_BUG_ON(!i915->media_gt && !gt_is_root(pxp->ctrl_gt)) will do. > > > +} > > + > > /** > > * intel_pxp_irq_handler - Handles PXP interrupts. > > * @pxp: pointer to pxp struct > > @@ -29,7 +46,7 @@ void intel_pxp_irq_handler(struct intel_pxp *pxp, u16 iir) > > if (GEM_WARN_ON(!intel_pxp_is_enabled(pxp))) > > return; > > > > - gt = pxp->ctrl_gt; > > + gt = intel_pxp_get_irq_gt(pxp); > > Here also we only have the assert below i will follow the above recommendation. > > Daniele > > > > > lockdep_assert_held(gt->irq_lock); > > > > @@ -68,7 +85,7 @@ static inline void pxp_irq_reset(struct intel_gt *gt) > > > > void intel_pxp_irq_enable(struct intel_pxp *pxp) > > { > > - struct intel_gt *gt = pxp->ctrl_gt; > > + struct intel_gt *gt = intel_pxp_get_irq_gt(pxp); > > > > spin_lock_irq(gt->irq_lock); > > > > @@ -83,7 +100,7 @@ void intel_pxp_irq_enable(struct intel_pxp *pxp) > > > > void intel_pxp_irq_disable(struct intel_pxp *pxp) > > { > > - struct intel_gt *gt = pxp->ctrl_gt; > > + struct intel_gt *gt = intel_pxp_get_irq_gt(pxp); > > > > /* > > * We always need to submit a global termination when we re-enable > > the > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.h > >
Re: [Lsf-pc] [LSF/MM/BPF proposal]: Physr discussion
Matthew Wilcox wrote: > On Mon, Jan 23, 2023 at 11:36:51AM -0800, Dan Williams wrote: > > Jason Gunthorpe via Lsf-pc wrote: > > > I would like to have a session at LSF to talk about Matthew's > > > physr discussion starter: > > > > > > https://lore.kernel.org/linux-mm/ydykweu0htv8m...@casper.infradead.org/ > > > > > > I have become interested in this with some immediacy because of > > > IOMMUFD and this other discussion with Christoph: > > > > > > > > > https://lore.kernel.org/kvm/4-v2-472615b3877e+28f7-vfio_dma_buf_...@nvidia.com/ > > > > I think this is a worthwhile discussion. My main hangup with 'struct > > page' elimination in general is that if anything needs to be allocated > > You're the first one to bring up struct page elimination. Neither Jason > nor I have that as our motivation. Oh, ok, then maybe I misread the concern in the vfio discussion. I thought the summary there is debating the ongoing requirement for 'struct page' for P2PDMA?
Re: [PATCH 10/10] drm/fbdev-generic: Rename struct fb_info 'fbi' to 'info'
Hi Thomas, a quick drive-by comment. On Mon, Jan 23, 2023 at 11:05:59AM +0100, Thomas Zimmermann wrote: > The generic fbdev emulation names variables of type struct fb_info > both 'fbi' and 'info'. The latter seems to be more common in fbdev > code, so name fbi accordingly. > > Also replace the duplicate variable in drm_fbdev_fb_destroy(). > > Signed-off-by: Thomas Zimmermann > --- > drivers/gpu/drm/drm_fbdev_generic.c | 49 ++--- > 1 file changed, 24 insertions(+), 25 deletions(-) > > diff --git a/drivers/gpu/drm/drm_fbdev_generic.c > b/drivers/gpu/drm/drm_fbdev_generic.c > index 49a0bba86ce7..7633da5c13c3 100644 > --- a/drivers/gpu/drm/drm_fbdev_generic.c > +++ b/drivers/gpu/drm/drm_fbdev_generic.c > @@ -46,17 +46,16 @@ static int drm_fbdev_fb_release(struct fb_info *info, int > user) > static void drm_fbdev_fb_destroy(struct fb_info *info) > { > struct drm_fb_helper *fb_helper = info->par; > - struct fb_info *fbi = fb_helper->info; > void *shadow = NULL; > > if (!fb_helper->dev) > return; > > - if (fbi) { > - if (fbi->fbdefio) > - fb_deferred_io_cleanup(fbi); > + if (info) { As info is already used above to find fb_helper, this check is redundant. Sam > + if (info->fbdefio) > + fb_deferred_io_cleanup(info); > if (drm_fbdev_use_shadow_fb(fb_helper)) > - shadow = fbi->screen_buffer; > + shadow = info->screen_buffer; > } > > drm_fb_helper_fini(fb_helper); > @@ -173,7 +172,7 @@ static int drm_fbdev_fb_probe(struct drm_fb_helper > *fb_helper, > struct drm_device *dev = fb_helper->dev; > struct drm_client_buffer *buffer; > struct drm_framebuffer *fb; > - struct fb_info *fbi; > + struct fb_info *info; > u32 format; > struct iosys_map map; > int ret; > @@ -192,35 +191,35 @@ static int drm_fbdev_fb_probe(struct drm_fb_helper > *fb_helper, > fb_helper->fb = buffer->fb; > fb = buffer->fb; > > - fbi = drm_fb_helper_alloc_info(fb_helper); > - if (IS_ERR(fbi)) > - return PTR_ERR(fbi); > + info = drm_fb_helper_alloc_info(fb_helper); > + if (IS_ERR(info)) > + return PTR_ERR(info); > > - fbi->fbops = _fbdev_fb_ops; > - fbi->screen_size = sizes->surface_height * fb->pitches[0]; > - fbi->fix.smem_len = fbi->screen_size; > - fbi->flags = FBINFO_DEFAULT; > + info->fbops = _fbdev_fb_ops; > + info->screen_size = sizes->surface_height * fb->pitches[0]; > + info->fix.smem_len = info->screen_size; > + info->flags = FBINFO_DEFAULT; > > - drm_fb_helper_fill_info(fbi, fb_helper, sizes); > + drm_fb_helper_fill_info(info, fb_helper, sizes); > > if (drm_fbdev_use_shadow_fb(fb_helper)) { > - fbi->screen_buffer = vzalloc(fbi->screen_size); > - if (!fbi->screen_buffer) > + info->screen_buffer = vzalloc(info->screen_size); > + if (!info->screen_buffer) > return -ENOMEM; > - fbi->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST; > + info->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST; > > - fbi->fbdefio = _fbdev_defio; > - fb_deferred_io_init(fbi); > + info->fbdefio = _fbdev_defio; > + fb_deferred_io_init(info); > } else { > /* buffer is mapped for HW framebuffer */ > ret = drm_client_buffer_vmap(fb_helper->buffer, ); > if (ret) > return ret; > if (map.is_iomem) { > - fbi->screen_base = map.vaddr_iomem; > + info->screen_base = map.vaddr_iomem; > } else { > - fbi->screen_buffer = map.vaddr; > - fbi->flags |= FBINFO_VIRTFB; > + info->screen_buffer = map.vaddr; > + info->flags |= FBINFO_VIRTFB; > } > > /* > @@ -229,10 +228,10 @@ static int drm_fbdev_fb_probe(struct drm_fb_helper > *fb_helper, >* case. >*/ > #if IS_ENABLED(CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM) > - if (fb_helper->hint_leak_smem_start && fbi->fix.smem_start == 0 > && > + if (fb_helper->hint_leak_smem_start && info->fix.smem_start == > 0 && > !drm_WARN_ON_ONCE(dev, map.is_iomem)) > - fbi->fix.smem_start = > - page_to_phys(virt_to_page(fbi->screen_buffer)); > + info->fix.smem_start = > + page_to_phys(virt_to_page(info->screen_buffer)); > #endif > } > > -- > 2.39.0
Re: [PATCH 85/86] drm: move drm_timeout_abs_to_jiffies to drm_util
Hi Thomas, On Mon, Jan 23, 2023 at 09:57:13AM +0100, Thomas Zimmermann wrote: > Hi Sam, > > please see my comment below. > > Am 21.01.23 um 21:09 schrieb Sam Ravnborg via B4 Submission Endpoint: > > From: Sam Ravnborg > > > > drm_timeout_abs_to_jiffies() was implmented in drm_syncobj where > > it really did not belong. Create a drm_util file and move the > > implementation. Likewise move the prototype and update all users. > > > > Suggested-by: Daniel Vetter > > [https://lore.kernel.org/dri-devel/20190527185311.GS21222@phenom.ffwll.local/] > > Cc: Daniel Vetter > > Signed-off-by: Sam Ravnborg > > --- > > drivers/accel/ivpu/ivpu_gem.c | 2 +- > > drivers/gpu/drm/Makefile| 1 + > > drivers/gpu/drm/drm_syncobj.c | 34 > > drivers/gpu/drm/drm_util.c | 40 > > + > > drivers/gpu/drm/lima/lima_gem.c | 2 +- > > drivers/gpu/drm/panfrost/panfrost_drv.c | 2 +- > > drivers/gpu/drm/tegra/uapi.c| 2 +- > > include/drm/drm_util.h | 1 + > > include/drm/drm_utils.h | 2 -- > > 9 files changed, 46 insertions(+), 40 deletions(-) > > > > diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c > > index d1f923971b4c..55aa94ba6c10 100644 > > --- a/drivers/accel/ivpu/ivpu_gem.c > > +++ b/drivers/accel/ivpu/ivpu_gem.c > > @@ -12,7 +12,7 @@ > > #include > > #include > > #include > > -#include > > +#include > > #include "ivpu_drv.h" > > #include "ivpu_gem.h" > > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile > > index ab4460fcd63f..561b93d19685 100644 > > --- a/drivers/gpu/drm/Makefile > > +++ b/drivers/gpu/drm/Makefile > > @@ -42,6 +42,7 @@ drm-y := \ > > drm_syncobj.o \ > > drm_sysfs.o \ > > drm_trace_points.o \ > > + drm_util.o \ > > drm_vblank.o \ > > drm_vblank_work.o \ > > drm_vma_manager.o \ > > diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c > > index 0c2be8360525..35f5416c5cfe 100644 > > --- a/drivers/gpu/drm/drm_syncobj.c > > +++ b/drivers/gpu/drm/drm_syncobj.c > > @@ -197,7 +197,6 @@ > > #include > > #include > > #include > > -#include > > #include "drm_internal.h" > > @@ -1114,39 +1113,6 @@ static signed long > > drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, > > return timeout; > > } > > -/** > > - * drm_timeout_abs_to_jiffies - calculate jiffies timeout from absolute > > value > > - * > > - * @timeout_nsec: timeout nsec component in ns, 0 for poll > > - * > > - * Calculate the timeout in jiffies from an absolute time in sec/nsec. > > - */ > > -signed long drm_timeout_abs_to_jiffies(int64_t timeout_nsec) Thanks for the critical look at this! > > This function converts an absolute timeout in nsec to a relative timeout in > jiffies. (?) > > It appears to me as if this helper should not exist. It uses a mixture of > different time interfaces; combined with hardcoded policy for 0 and > MAX_SCHEDULE_TIMEOUT. > > There are only 3 callers of this helper. I think we should consider inlining > it in each. > > As part of this, maybe the use of ktime could go away. Convert nsecs to > jiffies and do the rest of the computation in jiffies. I blindly copied the existing function and did not consider the implementation. Looking for a helper that do what we needs here turned up empty. I also looked at your suggestion to do: nsec in absolute => jiffies in absolute => jiffies in relative But did not find something that is better than what we have. I will leave it for now, and focus on the other parts of the patchset. In the vain hope someone else takes a look. Sam
Re: [RFC PATCH] drm: Create documentation about device resets
Am 23.01.23 um 21:26 schrieb André Almeida: Create a document that specifies how to deal with DRM device resets for kernel and userspace drivers. Signed-off-by: André Almeida --- Documentation/gpu/drm-reset.rst | 51 + Documentation/gpu/index.rst | 1 + 2 files changed, 52 insertions(+) create mode 100644 Documentation/gpu/drm-reset.rst diff --git a/Documentation/gpu/drm-reset.rst b/Documentation/gpu/drm-reset.rst new file mode 100644 index ..0dd11a469cf9 --- /dev/null +++ b/Documentation/gpu/drm-reset.rst @@ -0,0 +1,51 @@ + +DRM Device Reset + + +The GPU stack is really complex and is prone to errors, from hardware bugs, +faulty applications and everything in the many layers in between. To recover +from this kind of state, sometimes is needed to reset the GPU. Unproper handling +of GPU resets can lead to an unstable userspace. This page describes what's the +expected behaviour from DRM drivers to do in those situations, from usermode +drivers and compositors as well. + +Robustness +-- + +First of all, application robust APIs, when available, should be used. This +allows the application to correctly recover and continue to run after a reset. +Apps that doesn't use this should be promptly killed when the kernel driver +detects that it's in broken state. Specifically guidelines for some APIs: + +- OpenGL: During a reset, KMD kill processes that haven't ARB Robustness + enabled, assuming they can't recover. This is a pretty clear NAK from my side to this approach. The KMD should never mess with an userspace process directly in such a way. Instead use something like this "OpenGL: KMD signals the abortion of submitted commands and the UMD should then react accordingly and abort the application.". +- Vulkan: Assumes that every app is able to deal with ``VK_ERROR_DEVICE_LOST``, + so KMD doesn't kill any. If it doesn't do it right, it's considered a broken + application and UMD will deal with it. Again, pleas remove the "KMD kill" reference. + +Kernel mode driver +-- + +The KMD should be able to detect that something is wrong with the application Please replace *should* with *must* here, this is mandatory or otherwise core memory management can run into deadlocks during reclaim. Regards, Christian. +and that a reset is needed to take place to recover the device (e.g. an endless +wait). It needs to properly track the context that is broken and mark it as +dead, so any other syscalls to that context should be further rejected. The +other contexts should be preserved when possible, avoid crashing the rest of +userspace. KMD can ban a file descriptor that keeps causing resets, as it's +likely in a broken loop. + +User mode driver + + +During a reset, UMD should be aware that rejected syscalls indicates that the +context is broken and for robust apps the recovery should happen for the +context. Non-robust apps would be already terminated by KMD. If no new context +is created for some time, it is assumed that the recovery didn't work, so UMD +should terminate it. + +Compositors +--- + +(In the long term) compositors should be robust as well to properly deal with it +errors. Init systems should be aware of the compositor status and reset it if is +broken. diff --git a/Documentation/gpu/index.rst b/Documentation/gpu/index.rst index b99dede9a5b1..300b2529bd39 100644 --- a/Documentation/gpu/index.rst +++ b/Documentation/gpu/index.rst @@ -9,6 +9,7 @@ Linux GPU Driver Developer's Guide drm-mm drm-kms drm-kms-helpers + drm-reset drm-uapi drm-usage-stats driver-uapi
[PATCH v3 03/10] iommu: Add a gfp parameter to iommu_map_sg()
Follow the pattern for iommu_map() and remove iommu_map_sg_atomic(). This allows __iommu_dma_alloc_noncontiguous() to use a GFP_KERNEL allocation here, based on the provided gfp flags. Reviewed-by: Kevin Tian Signed-off-by: Jason Gunthorpe --- drivers/iommu/dma-iommu.c | 5 +++-- drivers/iommu/iommu.c | 26 ++ include/linux/iommu.h | 18 +- 3 files changed, 18 insertions(+), 31 deletions(-) diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 7016db569f81fc..72cfa24503b8bc 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -833,7 +833,8 @@ static struct page **__iommu_dma_alloc_noncontiguous(struct device *dev, arch_dma_prep_coherent(sg_page(sg), sg->length); } - ret = iommu_map_sg_atomic(domain, iova, sgt->sgl, sgt->orig_nents, ioprot); + ret = iommu_map_sg(domain, iova, sgt->sgl, sgt->orig_nents, ioprot, + GFP_ATOMIC); if (ret < 0 || ret < size) goto out_free_sg; @@ -1281,7 +1282,7 @@ static int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg, * We'll leave any physical concatenation to the IOMMU driver's * implementation - it knows better than we do. */ - ret = iommu_map_sg_atomic(domain, iova, sg, nents, prot); + ret = iommu_map_sg(domain, iova, sg, nents, prot, GFP_ATOMIC); if (ret < 0 || ret < iova_len) goto out_free_iova; diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 9412b420d07257..cc6e7c6bf72758 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2470,9 +2470,9 @@ size_t iommu_unmap_fast(struct iommu_domain *domain, } EXPORT_SYMBOL_GPL(iommu_unmap_fast); -static ssize_t __iommu_map_sg(struct iommu_domain *domain, unsigned long iova, - struct scatterlist *sg, unsigned int nents, int prot, - gfp_t gfp) +ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova, +struct scatterlist *sg, unsigned int nents, int prot, +gfp_t gfp) { const struct iommu_domain_ops *ops = domain->ops; size_t len = 0, mapped = 0; @@ -2480,6 +2480,13 @@ static ssize_t __iommu_map_sg(struct iommu_domain *domain, unsigned long iova, unsigned int i = 0; int ret; + might_sleep_if(gfpflags_allow_blocking(gfp)); + + /* Discourage passing strange GFP flags */ + if (WARN_ON_ONCE(gfp & (__GFP_COMP | __GFP_DMA | __GFP_DMA32 | + __GFP_HIGHMEM))) + return -EINVAL; + while (i <= nents) { phys_addr_t s_phys = sg_phys(sg); @@ -2519,21 +2526,8 @@ static ssize_t __iommu_map_sg(struct iommu_domain *domain, unsigned long iova, return ret; } - -ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova, -struct scatterlist *sg, unsigned int nents, int prot) -{ - might_sleep(); - return __iommu_map_sg(domain, iova, sg, nents, prot, GFP_KERNEL); -} EXPORT_SYMBOL_GPL(iommu_map_sg); -ssize_t iommu_map_sg_atomic(struct iommu_domain *domain, unsigned long iova, - struct scatterlist *sg, unsigned int nents, int prot) -{ - return __iommu_map_sg(domain, iova, sg, nents, prot, GFP_ATOMIC); -} - /** * report_iommu_fault() - report about an IOMMU fault to the IOMMU framework * @domain: the iommu domain where the fault has happened diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 521cd79700f4d8..d5c16dc33c87de 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -474,10 +474,8 @@ extern size_t iommu_unmap_fast(struct iommu_domain *domain, unsigned long iova, size_t size, struct iommu_iotlb_gather *iotlb_gather); extern ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova, - struct scatterlist *sg, unsigned int nents, int prot); -extern ssize_t iommu_map_sg_atomic(struct iommu_domain *domain, - unsigned long iova, struct scatterlist *sg, - unsigned int nents, int prot); + struct scatterlist *sg, unsigned int nents, + int prot, gfp_t gfp); extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova); extern void iommu_set_fault_handler(struct iommu_domain *domain, iommu_fault_handler_t handler, void *token); @@ -791,14 +789,7 @@ static inline size_t iommu_unmap_fast(struct iommu_domain *domain, static inline ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova, struct scatterlist *sg, - unsigned int nents, int prot) -{ - return -ENODEV; -} - -static inline ssize_t iommu_map_sg_atomic(struct
[PATCH v3 09/10] iommu/s390: Push the gfp parameter to the kmem_cache_alloc()'s
dma_alloc_cpu_table() and dma_alloc_page_table() are eventually called by iommufd through s390_iommu_map_pages() and it should not be forced to atomic. Thread the gfp parameter through the call chain starting from s390_iommu_map_pages(). Reviewed-by: Niklas Schnelle Reviewed-by: Matthew Rosato Signed-off-by: Jason Gunthorpe --- arch/s390/include/asm/pci_dma.h | 5 +++-- arch/s390/pci/pci_dma.c | 31 +-- drivers/iommu/s390-iommu.c | 15 +-- 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/arch/s390/include/asm/pci_dma.h b/arch/s390/include/asm/pci_dma.h index 91e63426bdc53f..7119c04c51c5c8 100644 --- a/arch/s390/include/asm/pci_dma.h +++ b/arch/s390/include/asm/pci_dma.h @@ -186,9 +186,10 @@ static inline unsigned long *get_st_pto(unsigned long entry) /* Prototypes */ void dma_free_seg_table(unsigned long); -unsigned long *dma_alloc_cpu_table(void); +unsigned long *dma_alloc_cpu_table(gfp_t gfp); void dma_cleanup_tables(unsigned long *); -unsigned long *dma_walk_cpu_trans(unsigned long *rto, dma_addr_t dma_addr); +unsigned long *dma_walk_cpu_trans(unsigned long *rto, dma_addr_t dma_addr, + gfp_t gfp); void dma_update_cpu_trans(unsigned long *entry, phys_addr_t page_addr, int flags); extern const struct dma_map_ops s390_pci_dma_ops; diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c index ea478d11fbd132..2f6d05d6da4f76 100644 --- a/arch/s390/pci/pci_dma.c +++ b/arch/s390/pci/pci_dma.c @@ -27,11 +27,11 @@ static int zpci_refresh_global(struct zpci_dev *zdev) zdev->iommu_pages * PAGE_SIZE); } -unsigned long *dma_alloc_cpu_table(void) +unsigned long *dma_alloc_cpu_table(gfp_t gfp) { unsigned long *table, *entry; - table = kmem_cache_alloc(dma_region_table_cache, GFP_ATOMIC); + table = kmem_cache_alloc(dma_region_table_cache, gfp); if (!table) return NULL; @@ -45,11 +45,11 @@ static void dma_free_cpu_table(void *table) kmem_cache_free(dma_region_table_cache, table); } -static unsigned long *dma_alloc_page_table(void) +static unsigned long *dma_alloc_page_table(gfp_t gfp) { unsigned long *table, *entry; - table = kmem_cache_alloc(dma_page_table_cache, GFP_ATOMIC); + table = kmem_cache_alloc(dma_page_table_cache, gfp); if (!table) return NULL; @@ -63,7 +63,7 @@ static void dma_free_page_table(void *table) kmem_cache_free(dma_page_table_cache, table); } -static unsigned long *dma_get_seg_table_origin(unsigned long *rtep) +static unsigned long *dma_get_seg_table_origin(unsigned long *rtep, gfp_t gfp) { unsigned long old_rte, rte; unsigned long *sto; @@ -72,7 +72,7 @@ static unsigned long *dma_get_seg_table_origin(unsigned long *rtep) if (reg_entry_isvalid(rte)) { sto = get_rt_sto(rte); } else { - sto = dma_alloc_cpu_table(); + sto = dma_alloc_cpu_table(gfp); if (!sto) return NULL; @@ -90,7 +90,7 @@ static unsigned long *dma_get_seg_table_origin(unsigned long *rtep) return sto; } -static unsigned long *dma_get_page_table_origin(unsigned long *step) +static unsigned long *dma_get_page_table_origin(unsigned long *step, gfp_t gfp) { unsigned long old_ste, ste; unsigned long *pto; @@ -99,7 +99,7 @@ static unsigned long *dma_get_page_table_origin(unsigned long *step) if (reg_entry_isvalid(ste)) { pto = get_st_pto(ste); } else { - pto = dma_alloc_page_table(); + pto = dma_alloc_page_table(gfp); if (!pto) return NULL; set_st_pto(, virt_to_phys(pto)); @@ -116,18 +116,19 @@ static unsigned long *dma_get_page_table_origin(unsigned long *step) return pto; } -unsigned long *dma_walk_cpu_trans(unsigned long *rto, dma_addr_t dma_addr) +unsigned long *dma_walk_cpu_trans(unsigned long *rto, dma_addr_t dma_addr, + gfp_t gfp) { unsigned long *sto, *pto; unsigned int rtx, sx, px; rtx = calc_rtx(dma_addr); - sto = dma_get_seg_table_origin([rtx]); + sto = dma_get_seg_table_origin([rtx], gfp); if (!sto) return NULL; sx = calc_sx(dma_addr); - pto = dma_get_page_table_origin([sx]); + pto = dma_get_page_table_origin([sx], gfp); if (!pto) return NULL; @@ -170,7 +171,8 @@ static int __dma_update_trans(struct zpci_dev *zdev, phys_addr_t pa, return -EINVAL; for (i = 0; i < nr_pages; i++) { - entry = dma_walk_cpu_trans(zdev->dma_table, dma_addr); + entry = dma_walk_cpu_trans(zdev->dma_table, dma_addr, + GFP_ATOMIC); if (!entry) {
[PATCH v3 10/10] iommu/s390: Use GFP_KERNEL in sleepable contexts
These contexts are sleepable, so use the proper annotation. The GFP_ATOMIC was added mechanically in the prior patches. Reviewed-by: Niklas Schnelle Reviewed-by: Matthew Rosato Signed-off-by: Jason Gunthorpe --- arch/s390/pci/pci_dma.c| 2 +- drivers/iommu/s390-iommu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c index 2f6d05d6da4f76..2d9b01d7ca4c5c 100644 --- a/arch/s390/pci/pci_dma.c +++ b/arch/s390/pci/pci_dma.c @@ -579,7 +579,7 @@ int zpci_dma_init_device(struct zpci_dev *zdev) spin_lock_init(>iommu_bitmap_lock); - zdev->dma_table = dma_alloc_cpu_table(GFP_ATOMIC); + zdev->dma_table = dma_alloc_cpu_table(GFP_KERNEL); if (!zdev->dma_table) { rc = -ENOMEM; goto out; diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c index 654ec4411fe36c..7dcfffed260e6b 100644 --- a/drivers/iommu/s390-iommu.c +++ b/drivers/iommu/s390-iommu.c @@ -52,7 +52,7 @@ static struct iommu_domain *s390_domain_alloc(unsigned domain_type) if (!s390_domain) return NULL; - s390_domain->dma_table = dma_alloc_cpu_table(GFP_ATOMIC); + s390_domain->dma_table = dma_alloc_cpu_table(GFP_KERNEL); if (!s390_domain->dma_table) { kfree(s390_domain); return NULL; -- 2.39.0
[PATCH v3 01/10] iommu: Add a gfp parameter to iommu_map()
The internal mechanisms support this, but instead of exposting the gfp to the caller it wrappers it into iommu_map() and iommu_map_atomic() Fix this instead of adding more variants for GFP_KERNEL_ACCOUNT. Reviewed-by: Kevin Tian Signed-off-by: Jason Gunthorpe --- arch/arm/mm/dma-mapping.c | 11 ++ .../drm/nouveau/nvkm/subdev/instmem/gk20a.c | 3 ++- drivers/gpu/drm/tegra/drm.c | 2 +- drivers/gpu/host1x/cdma.c | 2 +- drivers/infiniband/hw/usnic/usnic_uiom.c | 4 ++-- drivers/iommu/dma-iommu.c | 2 +- drivers/iommu/iommu.c | 22 +-- drivers/iommu/iommufd/pages.c | 6 +++-- drivers/media/platform/qcom/venus/firmware.c | 2 +- drivers/net/ipa/ipa_mem.c | 6 +++-- drivers/net/wireless/ath/ath10k/snoc.c| 2 +- drivers/net/wireless/ath/ath11k/ahb.c | 4 ++-- drivers/remoteproc/remoteproc_core.c | 5 +++-- drivers/vfio/vfio_iommu_type1.c | 9 drivers/vhost/vdpa.c | 2 +- include/linux/iommu.h | 4 ++-- 16 files changed, 48 insertions(+), 38 deletions(-) diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index c135f6e37a00ca..8bc01071474ab7 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -984,7 +984,8 @@ __iommu_create_mapping(struct device *dev, struct page **pages, size_t size, len = (j - i) << PAGE_SHIFT; ret = iommu_map(mapping->domain, iova, phys, len, - __dma_info_to_prot(DMA_BIDIRECTIONAL, attrs)); + __dma_info_to_prot(DMA_BIDIRECTIONAL, attrs), + GFP_KERNEL); if (ret < 0) goto fail; iova += len; @@ -1207,7 +1208,8 @@ static int __map_sg_chunk(struct device *dev, struct scatterlist *sg, prot = __dma_info_to_prot(dir, attrs); - ret = iommu_map(mapping->domain, iova, phys, len, prot); + ret = iommu_map(mapping->domain, iova, phys, len, prot, + GFP_KERNEL); if (ret < 0) goto fail; count += len >> PAGE_SHIFT; @@ -1379,7 +1381,8 @@ static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page, prot = __dma_info_to_prot(dir, attrs); - ret = iommu_map(mapping->domain, dma_addr, page_to_phys(page), len, prot); + ret = iommu_map(mapping->domain, dma_addr, page_to_phys(page), len, + prot, GFP_KERNEL); if (ret < 0) goto fail; @@ -1443,7 +1446,7 @@ static dma_addr_t arm_iommu_map_resource(struct device *dev, prot = __dma_info_to_prot(dir, attrs) | IOMMU_MMIO; - ret = iommu_map(mapping->domain, dma_addr, addr, len, prot); + ret = iommu_map(mapping->domain, dma_addr, addr, len, prot, GFP_KERNEL); if (ret < 0) goto fail; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c index 648ecf5a8fbc2a..a4ac94a2ab57fc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c @@ -475,7 +475,8 @@ gk20a_instobj_ctor_iommu(struct gk20a_instmem *imem, u32 npages, u32 align, u32 offset = (r->offset + i) << imem->iommu_pgshift; ret = iommu_map(imem->domain, offset, node->dma_addrs[i], - PAGE_SIZE, IOMMU_READ | IOMMU_WRITE); + PAGE_SIZE, IOMMU_READ | IOMMU_WRITE, + GFP_KERNEL); if (ret < 0) { nvkm_error(subdev, "IOMMU mapping failure: %d\n", ret); diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 7bd2e65c2a16c5..6ca9f396e55be4 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -1057,7 +1057,7 @@ void *tegra_drm_alloc(struct tegra_drm *tegra, size_t size, dma_addr_t *dma) *dma = iova_dma_addr(>carveout.domain, alloc); err = iommu_map(tegra->domain, *dma, virt_to_phys(virt), - size, IOMMU_READ | IOMMU_WRITE); + size, IOMMU_READ | IOMMU_WRITE, GFP_KERNEL); if (err < 0) goto free_iova; diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c index 103fda055394ab..4ddfcd2138c95b 100644 --- a/drivers/gpu/host1x/cdma.c +++ b/drivers/gpu/host1x/cdma.c @@ -105,7 +105,7 @@ static int host1x_pushbuffer_init(struct push_buffer *pb) pb->dma = iova_dma_addr(>iova, alloc); err = iommu_map(host1x->domain, pb->dma, pb->phys, size, - IOMMU_READ); +
[PATCH v3 08/10] iommu/intel: Use GFP_KERNEL in sleepable contexts
These contexts are sleepable, so use the proper annotation. The GFP_ATOMIC was added mechanically in the prior patches. Reviewed-by: Lu Baolu Reviewed-by: Kevin Tian Signed-off-by: Jason Gunthorpe --- drivers/iommu/intel/iommu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index e95f7703ce7b83..a1a66798e1f06c 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -2372,7 +2372,7 @@ static int iommu_domain_identity_map(struct dmar_domain *domain, return __domain_mapping(domain, first_vpfn, first_vpfn, last_vpfn - first_vpfn + 1, - DMA_PTE_READ|DMA_PTE_WRITE, GFP_ATOMIC); + DMA_PTE_READ|DMA_PTE_WRITE, GFP_KERNEL); } static int md_domain_init(struct dmar_domain *domain, int guest_width); @@ -2680,7 +2680,7 @@ static int copy_context_table(struct intel_iommu *iommu, if (!old_ce) goto out; - new_ce = alloc_pgtable_page(iommu->node, GFP_ATOMIC); + new_ce = alloc_pgtable_page(iommu->node, GFP_KERNEL); if (!new_ce) goto out_unmap; -- 2.39.0
[PATCH v3 02/10] iommu: Remove iommu_map_atomic()
There is only one call site and it can now just pass the GFP_ATOMIC to the normal iommu_map(). Reviewed-by: Kevin Tian Signed-off-by: Jason Gunthorpe --- drivers/iommu/dma-iommu.c | 2 +- drivers/iommu/iommu.c | 7 --- include/linux/iommu.h | 9 - 3 files changed, 1 insertion(+), 17 deletions(-) diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 8bdb65e7686ff9..7016db569f81fc 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -713,7 +713,7 @@ static dma_addr_t __iommu_dma_map(struct device *dev, phys_addr_t phys, if (!iova) return DMA_MAPPING_ERROR; - if (iommu_map_atomic(domain, iova, phys - iova_off, size, prot)) { + if (iommu_map(domain, iova, phys - iova_off, size, prot, GFP_ATOMIC)) { iommu_dma_free_iova(cookie, iova, size, NULL); return DMA_MAPPING_ERROR; } diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 7dac062b58f039..9412b420d07257 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2381,13 +2381,6 @@ int iommu_map(struct iommu_domain *domain, unsigned long iova, } EXPORT_SYMBOL_GPL(iommu_map); -int iommu_map_atomic(struct iommu_domain *domain, unsigned long iova, - phys_addr_t paddr, size_t size, int prot) -{ - return iommu_map(domain, iova, paddr, size, prot, GFP_ATOMIC); -} -EXPORT_SYMBOL_GPL(iommu_map_atomic); - static size_t __iommu_unmap_pages(struct iommu_domain *domain, unsigned long iova, size_t size, struct iommu_iotlb_gather *iotlb_gather) diff --git a/include/linux/iommu.h b/include/linux/iommu.h index d2020994f292db..521cd79700f4d8 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -468,8 +468,6 @@ extern struct iommu_domain *iommu_get_domain_for_dev(struct device *dev); extern struct iommu_domain *iommu_get_dma_domain(struct device *dev); extern int iommu_map(struct iommu_domain *domain, unsigned long iova, phys_addr_t paddr, size_t size, int prot, gfp_t gfp); -extern int iommu_map_atomic(struct iommu_domain *domain, unsigned long iova, - phys_addr_t paddr, size_t size, int prot); extern size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size); extern size_t iommu_unmap_fast(struct iommu_domain *domain, @@ -778,13 +776,6 @@ static inline int iommu_map(struct iommu_domain *domain, unsigned long iova, return -ENODEV; } -static inline int iommu_map_atomic(struct iommu_domain *domain, - unsigned long iova, phys_addr_t paddr, - size_t size, int prot) -{ - return -ENODEV; -} - static inline size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) { -- 2.39.0
[PATCH v3 05/10] iommufd: Use GFP_KERNEL_ACCOUNT for iommu_map()
iommufd follows the same design as KVM and uses memory cgroups to limit the amount of kernel memory a iommufd file descriptor can pin down. The various internal data structures already use GFP_KERNEL_ACCOUNT. However, one of the biggest consumers of kernel memory is the IOPTEs stored under the iommu_domain. Many drivers will allocate these at iommu_map() time and will trivially do the right thing if we pass in GFP_KERNEL_ACCOUNT. Reviewed-by: Kevin Tian Signed-off-by: Jason Gunthorpe --- drivers/iommu/iommufd/pages.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/iommufd/pages.c b/drivers/iommu/iommufd/pages.c index 22cc3bb0c6c55a..f8d92c9bb65b60 100644 --- a/drivers/iommu/iommufd/pages.c +++ b/drivers/iommu/iommufd/pages.c @@ -457,7 +457,7 @@ static int batch_iommu_map_small(struct iommu_domain *domain, while (size) { rc = iommu_map(domain, iova, paddr, PAGE_SIZE, prot, - GFP_KERNEL); + GFP_KERNEL_ACCOUNT); if (rc) goto err_unmap; iova += PAGE_SIZE; @@ -502,7 +502,7 @@ static int batch_to_domain(struct pfn_batch *batch, struct iommu_domain *domain, rc = iommu_map(domain, iova, PFN_PHYS(batch->pfns[cur]) + page_offset, next_iova - iova, area->iommu_prot, - GFP_KERNEL); + GFP_KERNEL_ACCOUNT); if (rc) goto err_unmap; iova = next_iova; -- 2.39.0
[PATCH v3 06/10] iommu/intel: Add a gfp parameter to alloc_pgtable_page()
This is eventually called by iommufd through intel_iommu_map_pages() and it should not be forced to atomic. Push the GFP_ATOMIC to all callers. Reviewed-by: Kevin Tian Reviewed-by: Lu Baolu Signed-off-by: Jason Gunthorpe --- drivers/iommu/intel/iommu.c | 14 +++--- drivers/iommu/intel/iommu.h | 2 +- drivers/iommu/intel/pasid.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 59df7e42fd533c..aa29561d3549b3 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -362,12 +362,12 @@ static int __init intel_iommu_setup(char *str) } __setup("intel_iommu=", intel_iommu_setup); -void *alloc_pgtable_page(int node) +void *alloc_pgtable_page(int node, gfp_t gfp) { struct page *page; void *vaddr = NULL; - page = alloc_pages_node(node, GFP_ATOMIC | __GFP_ZERO, 0); + page = alloc_pages_node(node, gfp | __GFP_ZERO, 0); if (page) vaddr = page_address(page); return vaddr; @@ -612,7 +612,7 @@ struct context_entry *iommu_context_addr(struct intel_iommu *iommu, u8 bus, if (!alloc) return NULL; - context = alloc_pgtable_page(iommu->node); + context = alloc_pgtable_page(iommu->node, GFP_ATOMIC); if (!context) return NULL; @@ -935,7 +935,7 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, if (!dma_pte_present(pte)) { uint64_t pteval; - tmp_page = alloc_pgtable_page(domain->nid); + tmp_page = alloc_pgtable_page(domain->nid, GFP_ATOMIC); if (!tmp_page) return NULL; @@ -1186,7 +1186,7 @@ static int iommu_alloc_root_entry(struct intel_iommu *iommu) { struct root_entry *root; - root = (struct root_entry *)alloc_pgtable_page(iommu->node); + root = (struct root_entry *)alloc_pgtable_page(iommu->node, GFP_ATOMIC); if (!root) { pr_err("Allocating root entry for %s failed\n", iommu->name); @@ -2676,7 +2676,7 @@ static int copy_context_table(struct intel_iommu *iommu, if (!old_ce) goto out; - new_ce = alloc_pgtable_page(iommu->node); + new_ce = alloc_pgtable_page(iommu->node, GFP_ATOMIC); if (!new_ce) goto out_unmap; @@ -4136,7 +4136,7 @@ static int md_domain_init(struct dmar_domain *domain, int guest_width) domain->max_addr = 0; /* always allocate the top pgd */ - domain->pgd = alloc_pgtable_page(domain->nid); + domain->pgd = alloc_pgtable_page(domain->nid, GFP_ATOMIC); if (!domain->pgd) return -ENOMEM; domain_flush_cache(domain, domain->pgd, PAGE_SIZE); diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h index 06e61e4748567a..ca9a035e0110af 100644 --- a/drivers/iommu/intel/iommu.h +++ b/drivers/iommu/intel/iommu.h @@ -737,7 +737,7 @@ int qi_submit_sync(struct intel_iommu *iommu, struct qi_desc *desc, extern int dmar_ir_support(void); -void *alloc_pgtable_page(int node); +void *alloc_pgtable_page(int node, gfp_t gfp); void free_pgtable_page(void *vaddr); void iommu_flush_write_buffer(struct intel_iommu *iommu); struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn); diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c index fb3c7020028d07..c5bf74e9372d62 100644 --- a/drivers/iommu/intel/pasid.c +++ b/drivers/iommu/intel/pasid.c @@ -200,7 +200,7 @@ static struct pasid_entry *intel_pasid_get_entry(struct device *dev, u32 pasid) retry: entries = get_pasid_table_from_pde([dir_index]); if (!entries) { - entries = alloc_pgtable_page(info->iommu->node); + entries = alloc_pgtable_page(info->iommu->node, GFP_ATOMIC); if (!entries) return NULL; -- 2.39.0
[PATCH v3 07/10] iommu/intel: Support the gfp argument to the map_pages op
Flow it down to alloc_pgtable_page() via pfn_to_dma_pte() and __domain_mapping(). Reviewed-by: Kevin Tian Reviewed-by: Lu Baolu Signed-off-by: Jason Gunthorpe --- drivers/iommu/intel/iommu.c | 24 +++- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index aa29561d3549b3..e95f7703ce7b83 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -908,7 +908,8 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id, #endif static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, - unsigned long pfn, int *target_level) + unsigned long pfn, int *target_level, + gfp_t gfp) { struct dma_pte *parent, *pte; int level = agaw_to_level(domain->agaw); @@ -935,7 +936,7 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, if (!dma_pte_present(pte)) { uint64_t pteval; - tmp_page = alloc_pgtable_page(domain->nid, GFP_ATOMIC); + tmp_page = alloc_pgtable_page(domain->nid, gfp); if (!tmp_page) return NULL; @@ -2150,7 +2151,8 @@ static void switch_to_super_page(struct dmar_domain *domain, while (start_pfn <= end_pfn) { if (!pte) - pte = pfn_to_dma_pte(domain, start_pfn, ); + pte = pfn_to_dma_pte(domain, start_pfn, , +GFP_ATOMIC); if (dma_pte_present(pte)) { dma_pte_free_pagetable(domain, start_pfn, @@ -2172,7 +2174,8 @@ static void switch_to_super_page(struct dmar_domain *domain, static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, -unsigned long phys_pfn, unsigned long nr_pages, int prot) +unsigned long phys_pfn, unsigned long nr_pages, int prot, +gfp_t gfp) { struct dma_pte *first_pte = NULL, *pte = NULL; unsigned int largepage_lvl = 0; @@ -2202,7 +2205,8 @@ __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, largepage_lvl = hardware_largepage_caps(domain, iov_pfn, phys_pfn, nr_pages); - pte = pfn_to_dma_pte(domain, iov_pfn, _lvl); + pte = pfn_to_dma_pte(domain, iov_pfn, _lvl, +gfp); if (!pte) return -ENOMEM; first_pte = pte; @@ -2368,7 +2372,7 @@ static int iommu_domain_identity_map(struct dmar_domain *domain, return __domain_mapping(domain, first_vpfn, first_vpfn, last_vpfn - first_vpfn + 1, - DMA_PTE_READ|DMA_PTE_WRITE); + DMA_PTE_READ|DMA_PTE_WRITE, GFP_ATOMIC); } static int md_domain_init(struct dmar_domain *domain, int guest_width); @@ -4298,7 +4302,7 @@ static int intel_iommu_map(struct iommu_domain *domain, the low bits of hpa would take us onto the next page */ size = aligned_nrpages(hpa, size); return __domain_mapping(dmar_domain, iova >> VTD_PAGE_SHIFT, - hpa >> VTD_PAGE_SHIFT, size, prot); + hpa >> VTD_PAGE_SHIFT, size, prot, gfp); } static int intel_iommu_map_pages(struct iommu_domain *domain, @@ -4333,7 +4337,8 @@ static size_t intel_iommu_unmap(struct iommu_domain *domain, /* Cope with horrid API which requires us to unmap more than the size argument if it happens to be a large-page mapping. */ - BUG_ON(!pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, )); + BUG_ON(!pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, , + GFP_ATOMIC)); if (size < VTD_PAGE_SIZE << level_to_offset_bits(level)) size = VTD_PAGE_SIZE << level_to_offset_bits(level); @@ -4392,7 +4397,8 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain, int level = 0; u64 phys = 0; - pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, ); + pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, , +GFP_ATOMIC); if (pte && dma_pte_present(pte)) phys = dma_pte_addr(pte) + (iova & (BIT_MASK(level_to_offset_bits(level) + -- 2.39.0
[PATCH v3 00/10] Let iommufd charge IOPTE allocations to the memory cgroup
iommufd follows the same design as KVM and uses memory cgroups to limit the amount of kernel memory a iommufd file descriptor can pin down. The various internal data structures already use GFP_KERNEL_ACCOUNT to charge its own memory. However, one of the biggest consumers of kernel memory is the IOPTEs stored under the iommu_domain and these allocations are not tracked. This series is the first step in fixing it. The iommu driver contract already includes a 'gfp' argument to the map_pages op, allowing iommufd to specify GFP_KERNEL_ACCOUNT and then having the driver allocate the IOPTE tables with that flag will capture a significant amount of the allocations. Update the iommu_map() API to pass in the GFP argument, and fix all call sites. Replace iommu_map_atomic(). Audit the "enterprise" iommu drivers to make sure they do the right thing. Intel and S390 ignore the GFP argument and always use GFP_ATOMIC. This is problematic for iommufd anyhow, so fix it. AMD and ARM SMMUv2/3 are already correct. A follow up series will be needed to capture the allocations made when the iommu_domain itself is allocated, which will complete the job. v3: - Leave a GFP_ATOMIC in "Add a gfp parameter to iommu_map_sg()" and move the conversion to gfp argument to "Use the gfp parameter in __iommu_dma_alloc_noncontiguous()" - Mask off the zone/policy flags from gfp before doing internal allocations and add a comment about Robin's note that this is to keep the buffer and internal seperate. v2: https://lore.kernel.org/r/0-v2-ce66f632bd0d+484-iommu_map_gfp_...@nvidia.com - Prohibit bad GFP flags in the iommu wrappers - Split out the new GFP_KERNEL usages into dedicated patches so it is easier to check. No code change after the full series v1: https://lore.kernel.org/r/0-v1-6e8b3997c46d+89e-iommu_map_gfp_...@nvidia.com Jason Gunthorpe (10): iommu: Add a gfp parameter to iommu_map() iommu: Remove iommu_map_atomic() iommu: Add a gfp parameter to iommu_map_sg() iommu/dma: Use the gfp parameter in __iommu_dma_alloc_noncontiguous() iommufd: Use GFP_KERNEL_ACCOUNT for iommu_map() iommu/intel: Add a gfp parameter to alloc_pgtable_page() iommu/intel: Support the gfp argument to the map_pages op iommu/intel: Use GFP_KERNEL in sleepable contexts iommu/s390: Push the gfp parameter to the kmem_cache_alloc()'s iommu/s390: Use GFP_KERNEL in sleepable contexts arch/arm/mm/dma-mapping.c | 11 ++-- arch/s390/include/asm/pci_dma.h | 5 +- arch/s390/pci/pci_dma.c | 31 ++- .../drm/nouveau/nvkm/subdev/instmem/gk20a.c | 3 +- drivers/gpu/drm/tegra/drm.c | 2 +- drivers/gpu/host1x/cdma.c | 2 +- drivers/infiniband/hw/usnic/usnic_uiom.c | 4 +- drivers/iommu/dma-iommu.c | 18 +-- drivers/iommu/intel/iommu.c | 36 +++-- drivers/iommu/intel/iommu.h | 2 +- drivers/iommu/intel/pasid.c | 2 +- drivers/iommu/iommu.c | 53 +++ drivers/iommu/iommufd/pages.c | 6 ++- drivers/iommu/s390-iommu.c| 15 +++--- drivers/media/platform/qcom/venus/firmware.c | 2 +- drivers/net/ipa/ipa_mem.c | 6 ++- drivers/net/wireless/ath/ath10k/snoc.c| 2 +- drivers/net/wireless/ath/ath11k/ahb.c | 4 +- drivers/remoteproc/remoteproc_core.c | 5 +- drivers/vfio/vfio_iommu_type1.c | 9 ++-- drivers/vhost/vdpa.c | 2 +- include/linux/iommu.h | 31 +++ 22 files changed, 126 insertions(+), 125 deletions(-) base-commit: 5dc4c995db9eb45f6373a956eb1f69460e69e6d4 -- 2.39.0
[PATCH v3 04/10] iommu/dma: Use the gfp parameter in __iommu_dma_alloc_noncontiguous()
This function does an allocation of a buffer to return to the caller and then goes on to allocate some internal memory, eg the scatterlist and IOPTEs. Instead of hard wiring GFP_KERNEL and a wrong GFP_ATOMIC, continue to use the passed in gfp flags for all of the allocations. Clear the zone and policy bits that are only relevant for the buffer allocation before re-using them for internal allocations. Auditing says this is never called from an atomic context, so the GFP_ATOMIC is the incorrect flag. Reviewed-by: Kevin Tian Signed-off-by: Jason Gunthorpe --- drivers/iommu/dma-iommu.c | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 72cfa24503b8bc..c99e4bc55d8cb0 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -822,7 +822,14 @@ static struct page **__iommu_dma_alloc_noncontiguous(struct device *dev, if (!iova) goto out_free_pages; - if (sg_alloc_table_from_pages(sgt, pages, count, 0, size, GFP_KERNEL)) + /* +* Remove the zone/policy flags from the GFP - these are applied to the +* __iommu_dma_alloc_pages() but are not used for the supporting +* internal allocations that follow. +*/ + gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM | __GFP_COMP); + + if (sg_alloc_table_from_pages(sgt, pages, count, 0, size, gfp)) goto out_free_iova; if (!(ioprot & IOMMU_CACHE)) { @@ -834,7 +841,7 @@ static struct page **__iommu_dma_alloc_noncontiguous(struct device *dev, } ret = iommu_map_sg(domain, iova, sgt->sgl, sgt->orig_nents, ioprot, - GFP_ATOMIC); + gfp); if (ret < 0 || ret < size) goto out_free_sg; -- 2.39.0
Re: [PATCH v4 1/7] drm/i915: Fix request locking during error capture & debugfs dump
On 1/23/2023 09:51, Tvrtko Ursulin wrote: On 20/01/2023 23:28, john.c.harri...@intel.com wrote: From: John Harrison When GuC support was added to error capture, the locking around the request object was broken. Fix it up. The context based search manages the spinlocking around the search internally. So it needs to grab the reference count internally as well. The execlist only request based search relies on external locking, so it needs an external reference count but within the spinlock not outside it. The only other caller of the context based search is the code for dumping engine state to debugfs. That code wasn't previously getting an explicit reference at all as it does everything while holding the execlist specific spinlock. So, that needs updaing as well as that spinlock doesn't help when using GuC submission. Rather than trying to conditionally get/put depending on submission model, just change it to always do the get/put. In addition, intel_guc_find_hung_context() was not acquiring the correct spinlock before searching the request list. So fix that up too. While at it, add some extra whitespace padding for readability. Is this part splittable into a separate patch? I guess it could but it seems closely related to all the other locking fix ups in this patch. v2: Explicitly document adding an extra blank line in some dense code (Andy Shevchenko). Fix multiple potential null pointer derefs in case of no request found (some spotted by Tvrtko, but there was more!). Also fix a leaked request in case of !started and another in __guc_reset_context now that intel_context_find_active_request is actually reference counting the returned request. v3: Add a _get suffix to intel_context_find_active_request now that it grabs a reference (Daniele). Fixes: dc0dad365c5e ("drm/i915/guc: Fix for error capture after full GPU reset with GuC") Fixes: 573ba126aef3 ("drm/i915/guc: Capture error state on context reset") Cc: Matthew Brost Cc: John Harrison Cc: Jani Nikula Cc: Joonas Lahtinen Cc: Rodrigo Vivi Cc: Tvrtko Ursulin Cc: Daniele Ceraolo Spurio Cc: Andrzej Hajda Cc: Matthew Auld Cc: Matt Roper Cc: Umesh Nerlige Ramappa Cc: Michael Cheng Cc: Lucas De Marchi Cc: Tejas Upadhyay Cc: Andy Shevchenko Cc: Aravind Iddamsetty Cc: Alan Previn Cc: Bruce Chang Cc: intel-...@lists.freedesktop.org Signed-off-by: John Harrison Reviewed-by: Daniele Ceraolo Spurio --- drivers/gpu/drm/i915/gt/intel_context.c | 4 +++- drivers/gpu/drm/i915/gt/intel_context.h | 3 +-- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 6 +- drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 14 +- drivers/gpu/drm/i915/i915_gpu_error.c | 13 ++--- 5 files changed, 28 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c index e94365b08f1ef..4285c1c71fa12 100644 --- a/drivers/gpu/drm/i915/gt/intel_context.c +++ b/drivers/gpu/drm/i915/gt/intel_context.c @@ -528,7 +528,7 @@ struct i915_request *intel_context_create_request(struct intel_context *ce) return rq; } -struct i915_request *intel_context_find_active_request(struct intel_context *ce) +struct i915_request *intel_context_find_active_request_get(struct intel_context *ce) TBH I don't "dig" this name, it's a bit on the long side and feels out of character. I won't insist it be changed, but if get really has to be included in the name I would be happy with intel_context_get_active_request(). Personally, I see the 'find' component as meaning it is a search not just a dereference of an existing pointer and therefore being a useful part of the name. I don't think there is a simple name that encapsulates everything that is going on here. But I don't feel too strongly about it if you really think the shorter version is better. One could add some kerneldoc... but it would be almost the only function in the whole of intel_context.h with such. Not sure if that is intentional because "obviously it should be obvious what a function is doing by reading the code and documentation is a waste of space that gets out of date and inaccurate" and we aren't meant to kerneldoc internal behaviour or if it's just the general lack of documentation for any driver code. { struct intel_context *parent = intel_context_to_parent(ce); struct i915_request *rq, *active = NULL; @@ -552,6 +552,8 @@ struct i915_request *intel_context_find_active_request(struct intel_context *ce) active = rq; } + if (active) + active = i915_request_get_rcu(active); spin_unlock_irqrestore(>guc_state.lock, flags); return active; diff --git a/drivers/gpu/drm/i915/gt/intel_context.h b/drivers/gpu/drm/i915/gt/intel_context.h index fb62b7b8cbcda..ccc80c6607ca8 100644 --- a/drivers/gpu/drm/i915/gt/intel_context.h +++ b/drivers/gpu/drm/i915/gt/intel_context.h @@ -268,8 +268,7 @@ int
Re: [PATCH v2 1/1] Docs/subsystem-apis: Remove '[The ]Linux' prefixes from titles of listed documents
On Sun, Jan 22, 2023 at 06:48:34PM +, SeongJae Park wrote: > Some documents that listed on subsystem-apis have 'Linux' or 'The Linux' > title prefixes. It's duplicated information, and makes finding the > document of interest with human eyes not easy. Remove the prefixes from > the titles. > > Signed-off-by: SeongJae Park PCI/index.rst change is fine with me: Acked-by: Bjorn Helgaas > --- > Changes from v1 > (https://lore.kernel.org/lkml/20230114194741.115855-1...@kernel.org/) > - Drop second patch (will post later for each subsystem) > > Documentation/PCI/index.rst| 6 +++--- > Documentation/cpu-freq/index.rst | 6 +++--- > Documentation/crypto/index.rst | 6 +++--- > Documentation/driver-api/index.rst | 6 +++--- > Documentation/gpu/index.rst| 6 +++--- > Documentation/hwmon/index.rst | 6 +++--- > Documentation/input/index.rst | 6 +++--- > Documentation/mm/index.rst | 6 +++--- > Documentation/peci/index.rst | 6 +++--- > Documentation/scheduler/index.rst | 6 +++--- > Documentation/scsi/index.rst | 6 +++--- > Documentation/sound/index.rst | 6 +++--- > Documentation/virt/index.rst | 6 +++--- > Documentation/watchdog/index.rst | 6 +++--- > 14 files changed, 42 insertions(+), 42 deletions(-) > > diff --git a/Documentation/PCI/index.rst b/Documentation/PCI/index.rst > index c17c87af1968..e73f84aebde3 100644 > --- a/Documentation/PCI/index.rst > +++ b/Documentation/PCI/index.rst > @@ -1,8 +1,8 @@ > .. SPDX-License-Identifier: GPL-2.0 > > -=== > -Linux PCI Bus Subsystem > -=== > += > +PCI Bus Subsystem > += > > .. toctree:: > :maxdepth: 2
Re: [PATCH v2 18/21] drm/amd/display: Fallback to 2020_YCBCR if the pixel encoding is not RGB
A new property to control YCC and subsampling would be the more complete path here. If we actually want to fix this in the short-term though, we should handle the YCC and RGB Colorspace values as equivalent, everywhere. Technically we're breaking the user space API here so it should be documented on the KMS property and other drivers must be adjusted accordingly as well. On Fri, Jan 13, 2023 at 5:26 PM Harry Wentland wrote: > > From: Joshua Ashton > > Userspace might not aware whether we're sending RGB or YCbCr > data to the display. If COLOR_SPACE_2020_RGB_FULLRANGE is > requested but the output encoding is YCbCr we should > send COLOR_SPACE_2020_YCBCR. > > Signed-off-by: Joshua Ashton > Signed-off-by: Harry Wentland > Cc: Pekka Paalanen > Cc: Sebastian Wick > Cc: vitaly.pros...@amd.com > Cc: Joshua Ashton > Cc: dri-devel@lists.freedesktop.org > Cc: amd-...@lists.freedesktop.org > Reviewed-by: Harry Wentland > --- > drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 - > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > index f74b125af31f..16940ea61b59 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > @@ -5184,7 +5184,10 @@ get_output_color_space(const struct dc_crtc_timing > *dc_crtc_timing, > color_space = COLOR_SPACE_ADOBERGB; > break; > case DRM_MODE_COLORIMETRY_BT2020_RGB: > - color_space = COLOR_SPACE_2020_RGB_FULLRANGE; > + if (dc_crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB) > + color_space = COLOR_SPACE_2020_RGB_FULLRANGE; > + else > + color_space = COLOR_SPACE_2020_YCBCR; > break; > case DRM_MODE_COLORIMETRY_BT2020_YCC: > color_space = COLOR_SPACE_2020_YCBCR; > -- > 2.39.0 >
[RFC PATCH] drm: Create documentation about device resets
Create a document that specifies how to deal with DRM device resets for kernel and userspace drivers. Signed-off-by: André Almeida --- Documentation/gpu/drm-reset.rst | 51 + Documentation/gpu/index.rst | 1 + 2 files changed, 52 insertions(+) create mode 100644 Documentation/gpu/drm-reset.rst diff --git a/Documentation/gpu/drm-reset.rst b/Documentation/gpu/drm-reset.rst new file mode 100644 index ..0dd11a469cf9 --- /dev/null +++ b/Documentation/gpu/drm-reset.rst @@ -0,0 +1,51 @@ + +DRM Device Reset + + +The GPU stack is really complex and is prone to errors, from hardware bugs, +faulty applications and everything in the many layers in between. To recover +from this kind of state, sometimes is needed to reset the GPU. Unproper handling +of GPU resets can lead to an unstable userspace. This page describes what's the +expected behaviour from DRM drivers to do in those situations, from usermode +drivers and compositors as well. + +Robustness +-- + +First of all, application robust APIs, when available, should be used. This +allows the application to correctly recover and continue to run after a reset. +Apps that doesn't use this should be promptly killed when the kernel driver +detects that it's in broken state. Specifically guidelines for some APIs: + +- OpenGL: During a reset, KMD kill processes that haven't ARB Robustness + enabled, assuming they can't recover. +- Vulkan: Assumes that every app is able to deal with ``VK_ERROR_DEVICE_LOST``, + so KMD doesn't kill any. If it doesn't do it right, it's considered a broken + application and UMD will deal with it. + +Kernel mode driver +-- + +The KMD should be able to detect that something is wrong with the application +and that a reset is needed to take place to recover the device (e.g. an endless +wait). It needs to properly track the context that is broken and mark it as +dead, so any other syscalls to that context should be further rejected. The +other contexts should be preserved when possible, avoid crashing the rest of +userspace. KMD can ban a file descriptor that keeps causing resets, as it's +likely in a broken loop. + +User mode driver + + +During a reset, UMD should be aware that rejected syscalls indicates that the +context is broken and for robust apps the recovery should happen for the +context. Non-robust apps would be already terminated by KMD. If no new context +is created for some time, it is assumed that the recovery didn't work, so UMD +should terminate it. + +Compositors +--- + +(In the long term) compositors should be robust as well to properly deal with it +errors. Init systems should be aware of the compositor status and reset it if is +broken. diff --git a/Documentation/gpu/index.rst b/Documentation/gpu/index.rst index b99dede9a5b1..300b2529bd39 100644 --- a/Documentation/gpu/index.rst +++ b/Documentation/gpu/index.rst @@ -9,6 +9,7 @@ Linux GPU Driver Developer's Guide drm-mm drm-kms drm-kms-helpers + drm-reset drm-uapi drm-usage-stats driver-uapi -- 2.39.1