Re: [PATCH] drm/exynos: dsi: Remove bridge node reference in error handling path in probe function
Hi, 20. 5. 11. 오전 12:48에 Christophe JAILLET 이(가) 쓴 글: > 'exynos_dsi_parse_dt()' takes a reference to 'dsi->in_bridge_node'. > This must be released in the error handling path. > > This patch is similar to commit 70505c2ef94b ("drm/exynos: dsi: Remove bridge > node reference in removal") > which fixed the issue in the remove function. > > Signed-off-by: Christophe JAILLET > --- > A Fixes tag could be required, but I've not been able to figure out which > one to use. > > I think that moving 'exynos_dsi_parse_dt()' in the probe could simplify > the error handling in the probe function. However, I don't know this code > well enough to play this game. So better safe than sorry. > So I've kept the logic in place and added goto everywhere. :( You could move exynos_dsi_parse_dt() call to the end of the probe function to handle the error simply. dsi->in_bridge_node is accessed in bind function and the probe function is called before the bind call. Could you rework and post it again? Thanks, Inki Dae > --- > drivers/gpu/drm/exynos/exynos_drm_dsi.c | 28 ++--- > 1 file changed, 20 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c > b/drivers/gpu/drm/exynos/exynos_drm_dsi.c > index 902938d2568f..2aa74c3dc733 100644 > --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c > +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c > @@ -1770,14 +1770,17 @@ static int exynos_dsi_probe(struct platform_device > *pdev) > if (ret) { > if (ret != -EPROBE_DEFER) > dev_info(dev, "failed to get regulators: %d\n", ret); > - return ret; > + goto err_put_in_bridge_node; > } > > dsi->clks = devm_kcalloc(dev, > dsi->driver_data->num_clks, sizeof(*dsi->clks), > GFP_KERNEL); > - if (!dsi->clks) > - return -ENOMEM; > + if (!dsi->clks) { > + ret = -ENOMEM; > + goto err_put_in_bridge_node; > + } > + > > for (i = 0; i < dsi->driver_data->num_clks; i++) { > dsi->clks[i] = devm_clk_get(dev, clk_names[i]); > @@ -1791,7 +1794,8 @@ static int exynos_dsi_probe(struct platform_device > *pdev) > > dev_info(dev, "failed to get the clock: %s\n", > clk_names[i]); > - return PTR_ERR(dsi->clks[i]); > + ret = PTR_ERR(dsi->clks[i]); > + goto err_put_in_bridge_node; > } > } > > @@ -1799,19 +1803,22 @@ static int exynos_dsi_probe(struct platform_device > *pdev) > dsi->reg_base = devm_ioremap_resource(dev, res); > if (IS_ERR(dsi->reg_base)) { > dev_err(dev, "failed to remap io region\n"); > - return PTR_ERR(dsi->reg_base); > + ret = PTR_ERR(dsi->reg_base); > + goto err_put_in_bridge_node; > } > > dsi->phy = devm_phy_get(dev, "dsim"); > if (IS_ERR(dsi->phy)) { > dev_info(dev, "failed to get dsim phy\n"); > - return PTR_ERR(dsi->phy); > + ret = PTR_ERR(dsi->phy); > + goto err_put_in_bridge_node; > } > > dsi->irq = platform_get_irq(pdev, 0); > if (dsi->irq < 0) { > dev_err(dev, "failed to request dsi irq resource\n"); > - return dsi->irq; > + ret = dsi->irq; > + goto err_put_in_bridge_node; > } > > irq_set_status_flags(dsi->irq, IRQ_NOAUTOEN); > @@ -1820,7 +1827,7 @@ static int exynos_dsi_probe(struct platform_device > *pdev) > dev_name(dev), dsi); > if (ret) { > dev_err(dev, "failed to request dsi irq\n"); > - return ret; > + goto err_put_in_bridge_node; > } > > platform_set_drvdata(pdev, >encoder); > @@ -1828,6 +1835,11 @@ static int exynos_dsi_probe(struct platform_device > *pdev) > pm_runtime_enable(dev); > > return component_add(dev, _dsi_component_ops); > + > +err_put_in_bridge_node: > + of_node_put(dsi->in_bridge_node); > + > + return ret; > } > > static int exynos_dsi_remove(struct platform_device *pdev) > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Nouveau] [PATCH 1/3] drm/radeon: remove AGP support
On Tue, May 12, 2020 at 4:52 PM Roy Spliet wrote: > > Op 12-05-2020 om 14:36 schreef Alex Deucher: > > On Tue, May 12, 2020 at 4:16 AM Michel Dänzer wrote: > >> > >> On 2020-05-11 10:12 p.m., Alex Deucher wrote: > >>> On Mon, May 11, 2020 at 1:17 PM Christian König > >>> wrote: > > AGP is deprecated for 10+ years now and not used any more on modern > hardware. > > Old hardware should continue to work in PCI mode. > >>> > >>> Might want to clarify that there is no loss of functionality here. > >>> Something like: > >>> > >>> "There is no loss of functionality here. GPUs will continue to > >>> function. This just drops the use of the AGP MMU in the chipset in > >>> favor of the MMU on the device which has proven to be much more > >>> reliable. Due to its unreliability, AGP support has been disabled on > >>> PowerPC for years already so there is no change on PowerPC." > >> > >> There's a difference between something being disabled by default or not > >> being available at all. We may decide it's worth it anyway, but let's do > >> it based on facts. > >> > > > > I didn't mean to imply that AGP GART support was already removed. But > > for the vast majority of users the end result is the same. If you > > knew enough re-enable AGP GART, you probably wouldn't have been as > > confused about what this patch set does either. To reiterate, this > > patch set does not remove support for AGP cards, it only removes the > > support for AGP GART. The cards will still be functional using the > > device GART. There may be performance tradeoffs there in some cases. > > I'll volunteer to be the one asking: how big is this performance > difference? Have any benchmarks been run before and after removal of AGP > GART code on affected nouveau/radeon systems? Or is this code being > dropped _just_ because it's cumbersome, with no regard for metrics that > determine the value of AGP GART support? > I don't think anyone has any solid numbers, just anecdotal from memory. I certainly don't have any functional AGP systems at this point. It's mostly just cumbersome and would allow us to clean ttm and probably improve stability at the same time. At least on the radeon side, the only native AGP cards were r1xx, r2xx, and some of the early r3xx boards. Once we switched to pcie mid-way through r3xx, everything was native pcie and the AGP cards used a pcie to AGP bridge chip so they had a decent on chip MMU. Those older cards topped out at maybe 32 or 64 MB of vram, so they are going to be hard pressed to deal with modern desktops anyway. No idea what sort of GART capabilities NV AGP hardware at this time had. Alex > Roy > > > > > Alex > > ___ > > Nouveau mailing list > > nouv...@lists.freedesktop.org > > https://lists.freedesktop.org/mailman/listinfo/nouveau > > > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] docs: dt: fix broken links due to txt->yaml renames
On Mon, May 04, 2020 at 11:30:20AM +0200, Mauro Carvalho Chehab wrote: > There are some new broken doc links due to yaml renames > at DT. Developers should really run: > > ./scripts/documentation-file-ref-check > > in order to solve those issues while submitting patches. > This tool can even fix most of the issues with: > > ./scripts/documentation-file-ref-check --fix > > Signed-off-by: Mauro Carvalho Chehab > --- > > PS.: This patch is against today's linux-next. That's not a base anyone can apply this patch against. > > > .../devicetree/bindings/display/bridge/sii902x.txt | 2 +- > .../devicetree/bindings/display/rockchip/rockchip-drm.yaml | 2 +- > .../devicetree/bindings/net/mediatek-bluetooth.txt | 2 +- > .../devicetree/bindings/sound/audio-graph-card.txt | 2 +- > .../devicetree/bindings/sound/st,sti-asoc-card.txt | 2 +- > Documentation/mips/ingenic-tcu.rst | 2 +- > MAINTAINERS | 6 +++--- > 7 files changed, 9 insertions(+), 9 deletions(-) ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v10 0/2] Panel rotation patches
On Thu, Apr 16, 2020 at 7:03 PM Dmitry Osipenko wrote: > > 15.04.2020 00:32, dbasehore . пишет: > > On Tue, Apr 14, 2020 at 2:18 PM Dmitry Osipenko wrote: > >> > >> 14.04.2020 22:32, dbasehore . пишет: > >>> Hi Dmitry, sorry for the late reply. > >>> > >>> On Sun, Mar 8, 2020 at 12:25 PM Dmitry Osipenko wrote: > > 06.03.2020 03:21, Derek Basehore пишет: > > This adds the plumbing for reading panel rotation from the devicetree > > and sets up adding a panel property for the panel orientation on > > Mediatek SoCs when a rotation is present. > > Hello Derek and everyone, > > I'm looking at adding display rotation support to NVIDIA Tegra DRM > driver because some devices have display panel physically mounted > upside-down, and thus, display controller's scan-out needs to be rotated > by 180° in this case. > > Derek, yours panel-rotation patches add support for assigning panel's > orientation to the connector, but then only primary display plane > receives rotation value in [1], while rotation needs to be applied to > all available overlay/cursor planes and this should happen in other > places than [1] as well. > >>> > >>> This is intended. We don't correct the output in the kernel. We > >>> instead rely on notifying userspace that the panel is rotated, then we > >>> handle it there. > >>> > > [1] drm_client_modeset_commit_atomic() > > Please also note that in a case of the scan-out rotation, plane's > coordinates need to be changed in accordance to the display's rotation. > > I looked briefly through the DRM code and my understanding that the DRM > core currently doesn't support use-case where scan-out needs to rotated > based on a panel's orientation, correct? Is it the use-case you're > working on for the Mediatek driver? > >>> > >>> Yes, we rely on userspace to rotate the output. The major reason for > >>> this is because there may not be a "free" hardware rotation that can > >>> be applied to the overlay. Sean Paul and others also preferred that > >>> userspace control what is output to the screen instead of the kernel > >>> taking care of it. This code just adds the drm property to the panel. > >>> > >> > >> Could you please explain what that userspace is? > > > > This was added for Chrome OS, which uses its own graphics stack, > > Ozone, instead of Xorg. > > > > Thank you very much for the clarification. > > It's probably not a big problem for something monolithic and customized > like ChromeOS to issue a software update in order to take into account > all specifics of a particular device, but this doesn't work nicely for a > generic software, like a usual Linux distro. > > >> AFAIK, things like Xorg modesetting don't support that orientation > >> property. > > In my case it's not only the display panel which is upside-down, but > also the touchscreen. Hence both display output and touchscreen input > need to be rotated at once, otherwise you'll end up with either display > or input being upside-down. > > The 180° rotation should be free on NVIDIA Tegra. There are no known > limitations for the planes and BSP kernel video driver handles the > plane's coordinates/framebuffer rotation within the driver. > > The kernel's input subsystem allows us to transparently (for userspace) > remap the touchscreen input (by specifying generic touchscreen > device-tree properties), while this is not the case for the DRM subsystem. > > @Thierry, @Sean, @Daniel, could you please help me to understand how a > coordinated display / input rotation could be implemented, making the > rotation transparent to the user (i.e. avoiding xorg.conf hacking and > etc)? It should be nice if display's output could be flipped within the > DRM driver, hiding this fact from userspace. I think the right thing to do is to fix userspace to respect this property, since that has the most communal benefit. However(!!) if you don't want to do that, how about inspecting the info->panel_orientation value after drm_panel_attach in tegra driver and then adjusting rotation values in the driver. Of course, you wouldn't want to expose the panel orientation property since you don't want userspaces to be double-rotating on you, but it's optional so you'd be fine. > > Will it be okay if we'll add a transparent-rotation support specifically > to the Tegra DRM driver? For example if device-tree contains > nvidia,display-flip-y property, then the Tegra DRM driver will take care > of rotating coordinates/framebuffer of the display planes. I don't think this is necessary, but it also wouldn't really be appropriate to put software attributes into devicetree anyways. Sean ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[pull] amdgpu, amdkfd drm-next-5.8
Hi Dave, Daniel, More stuff for 5.8. The following changes since commit b8020b0304c8f44e5e29f0b1a04d31e0bf68d26a: drm/amdkfd: Enable over-subscription with >1 GWS queue (2020-04-28 16:20:30 -0400) are available in the Git repository at: git://people.freedesktop.org/~agd5f/linux tags/amd-drm-next-5.8-2020-05-12 for you to fetch changes up to 37e4f052cc9749db608ad63e53acc49354c98200: drm/amd/amdgpu: remove defined but not used 'crtc_offsets' (2020-05-11 18:04:09 -0400) amd-drm-next-5.8-2020-05-12: amdgpu: - Misc cleanups - RAS fixes - Expose FP16 for modesetting - DP 1.4 compliance test fixes - Clockgating fixes - MAINTAINERS update - Soft recovery for gfx10 - Runtime PM cleanups - PSP code cleanups amdkfd: - Track GPU memory utilization per process - Report PCI domain in topology Alex Deucher (6): drm/amdgpu: force fbdev into vram drm/amdgpu: implement soft_recovery for gfx10 drm/amdgpu: drop pm_runtime_set_active drm/amdgpu: fix runpm logic in amdgpu_pmops_resume drm/amdgpu: drop extra runtime pm handling in resume pmop drm/amdgpu: only set DPM_FLAG_NEVER_SKIP for legacy ATPX BOCO Alvin Lee (1): drm/amd/display: Allow PState switch in VBLANK one display VACTIVE Andriy Gapon (1): amdgpu_acpi: add backlight control for the DC case Anthony Koo (3): drm/amd/display: add addition dc type to translate to dmub fw type drm/amd/display: move location of dmub_srv.h file drm/amd/display: Add struct field for future use Aric Cyr (2): drm/amd/display: Mode change with same timing causing long display blank drm/amd/display: 3.2.84 Arnd Bergmann (1): drm/amdgpu: allocate large structures dynamically Aurabindo Pillai (2): drm/amd/display: Prevent dpcd reads with passive dongles drm/amd/display: remove unused module/stats Bernard Zhao (2): drm/radeon: cleanup coding style a bit drm/amd/amdgpu: cleanup coding style a bit Boyuan Zhang (1): drm/amdgpu: change HWIP from UVD to VCN for VCN2.5 Chen Zhou (1): drm/amd/display: remove duplicate headers ChenTao (2): drm/radeon: fix unsigned comparison with 0 drm/amdgpu/navi10: fix unsigned comparison with 0 Christian König (1): drm/amdgpu: use the BAR if possible in amdgpu_device_vram_access v2 Chunming Zhou (1): MAINTAINERS: Remove me from amdgpu maintainers Daniel Kolesa (1): drm/amd/display: work around fp code being emitted outside of DC_FP_START/END Evan Quan (5): drm/amdgpu: put the audio codec into suspend state before gpu reset V3 drm/amdgpu: disable MGCG/MGLS also on gfx CG ungate drm/amdgpu: drop unnecessary cancel_delayed_work_sync on PG ungate drm/amd/powerplay: perform PG ungate prior to CG ungate drm/amdgpu: enable hibernate support on Navi1X Felix Kuehling (3): drm/amdkfd: Fix comment formatting drm/amdgpu: Add missing parameter description in comments drm/amdgpu: Use GEM obj reference for KFD BOs Hawking Zhang (7): drm/amdgpu: re-structue members for ip discovery drm/amdgpu: skip reservation of discovery tmr region in pre-Navi drm/amdgpu: switch to common xgmi ta helpers drm/amdgpu: switch to common ras ta helper drm/amdgpu: drop unused ras ta helper function drm/amdgpu: switch to common rlc_autoload helper drm/amdgpu: use node_id and node_size to calcualte dram_base_address Isabel Zhang (1): drm/amd/display: Add 4 to 1 MPC split support Jane Jian (1): drm/amd/powerplay: skip judging if baco support for Arcturus sriov Jason Yan (5): drm/amd/display: remove duplicate assignment of dcn21_funcs members drm/amdgpu/smu10: remove duplicate assignment of smu10_hwmgr_funcs members drm/amd/display: remove unused variable 'ret' in dm_suspend() drm/amd/display: remove variable "result" in dcn20_patch_unknown_plane_state() drm/amd/amdgpu: remove defined but not used 'crtc_offsets' Jerry (Fangzhi) Zuo (2): drm/amd/display: Check DMCU Exists Before Loading drm/amd/display: Add dm support for DP 1.4 Compliance edid corruption test John Clements (4): drm/amdgpu: update RAS error handling drm/amdgpu: update RAS TA to Host interface drm/amdgpu: update RAS sequence to parse TA flags drm/amdgpu: Fix bug in RAS invoke Leo (Hanghong) Ma (1): drm/amd/amdgpu: Update update_config() logic Lewis Huang (1): drm/amd/display: temporary clamp the vratio used to 1.0 Likun Gao (2): drm/amdgpu: check SMU NULL ptr on gfx hw init drm/amdgpu: update the method to set kcq queue mask Michel Dänzer (1): drm/amdgpu/dc: Use WARN_ON_ONCE for ASSERT Mukul Joshi (1): drm/amdkfd: Track GPU memory utilization per process Nathan Chancellor (1): drm/amdgpu: Avoid integer overflow in
Re: [RFC v2] drm/connector: Add support for privacy-screen properties (v2)
Hi, On 5/12/20 10:44 PM, mario.limoncie...@dell.com wrote: -Original Message- From: Hans de Goede Sent: Monday, May 11, 2020 12:47 PM To: Maarten Lankhorst; Maxime Ripard; Thomas Zimmermann; Daniel Vetter; David Airlie; Rajat Jain; Jani Nikula Cc: Hans de Goede; Pekka Paalanen; Limonciello, Mario; Quintanilla, Sonny; Jared Dominguez; Mark Pearson; dri-devel@lists.freedesktop.org Subject: [RFC v2] drm/connector: Add support for privacy-screen properties (v2) [EXTERNAL EMAIL] From: Rajat Jain Add support for generic electronic privacy screen properties, that can be added by systems that have an integrated EPS. Changes in v2 (Hans de Goede) - Create 2 properties, "privacy-screen sw-state" and "privacy-screen hw-state", to deal with devices where the OS might be locked out of making state changes - Write kerneldoc explaining how the 2 properties work together, what happens when changes to the state are made outside of the DRM code's control, etc. Signed-off-by: Rajat Jain Co-authored-by: Hans de Goede Signed-off-by: Hans de Goede --- Documentation/gpu/drm-kms.rst | 2 + drivers/gpu/drm/drm_atomic_uapi.c | 6 ++ drivers/gpu/drm/drm_connector.c | 100 ++ include/drm/drm_connector.h | 50 +++ 4 files changed, 158 insertions(+) diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index 906771e03103..b72b1e0db343 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -445,6 +445,8 @@ Property Types and Blob Property Support .. kernel-doc:: drivers/gpu/drm/drm_property.c :export: +.. _standard_connector_properties: + Standard Connector Properties - diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index a1e5e262bae2..e56a11208515 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -766,6 +766,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector, fence_ptr); } else if (property == connector->max_bpc_property) { state->max_requested_bpc = val; + } else if (property == connector->privacy_screen_sw_state_property) { + state->privacy_screen_sw_state = val; } else if (connector->funcs->atomic_set_property) { return connector->funcs->atomic_set_property(connector, state, property, val); @@ -842,6 +844,10 @@ drm_atomic_connector_get_property(struct drm_connector *connector, *val = 0; } else if (property == connector->max_bpc_property) { *val = state->max_requested_bpc; + } else if (property == connector->privacy_screen_sw_state_property) { + *val = state->privacy_screen_sw_state; + } else if (property == connector->privacy_screen_hw_state_property) { + *val = state->privacy_screen_hw_state; } else if (connector->funcs->atomic_get_property) { return connector->funcs->atomic_get_property(connector, state, property, val); diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 644f0ad10671..01360edc2376 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1186,6 +1186,45 @@ static const struct drm_prop_enum_list dp_colorspaces[] = { *can also expose this property to external outputs, in which case they *must support "None", which should be the default (since external screens *have a built-in scaler). + * + * privacy-screen sw-state, privacy-screen hw-state: + * These 2 optional properties can be used to query the state of the + * electronic privacy screen that is available on some displays; and in + * some cases also control the state. If a driver implements these + * properties then both properties must be present. + * + * "privacy-screen hw-state" is read-only and reflects the actual state + * of the privacy-screen, possible values: "Enabled", "Disabled, + * "Enabled, locked", "Disabled, locked". The locked states indicate + * that the state cannot be changed through the DRM API. E.g. there + * might be devices where the firmware-setup options, or a hardware + * slider-switch, offer always on / off modes. + * + * "privacy-screen sw-state" can be set to change the privacy-screen state + * when not locked. In this case the driver must update the hw-state + * property to reflect the new state on completion of the commit of the + * sw-state property. Setting the sw-state property when the hw-state is + * locked must be interpreted by the driver as a request to change the + * state to the set state when the hw-state becomes unlocked. E.g. if + * "privacy-screen hw-state" is "Enabled, locked" and the sw-state + *
Re: [RFC v2] drm/connector: Add support for privacy-screen properties (v2)
Hi, On 5/11/20 10:04 PM, Rajat Jain wrote: On Mon, May 11, 2020 at 10:47 AM Hans de Goede wrote: From: Rajat Jain Add support for generic electronic privacy screen properties, that can be added by systems that have an integrated EPS. Changes in v2 (Hans de Goede) - Create 2 properties, "privacy-screen sw-state" and "privacy-screen hw-state", to deal with devices where the OS might be locked out of making state changes - Write kerneldoc explaining how the 2 properties work together, what happens when changes to the state are made outside of the DRM code's control, etc. Signed-off-by: Rajat Jain Co-authored-by: Hans de Goede Signed-off-by: Hans de Goede Ack, Thanks for doing this. --- Documentation/gpu/drm-kms.rst | 2 + drivers/gpu/drm/drm_atomic_uapi.c | 6 ++ drivers/gpu/drm/drm_connector.c | 100 ++ include/drm/drm_connector.h | 50 +++ 4 files changed, 158 insertions(+) diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index 906771e03103..b72b1e0db343 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -445,6 +445,8 @@ Property Types and Blob Property Support .. kernel-doc:: drivers/gpu/drm/drm_property.c :export: +.. _standard_connector_properties: + Standard Connector Properties - diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index a1e5e262bae2..e56a11208515 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -766,6 +766,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector, fence_ptr); } else if (property == connector->max_bpc_property) { state->max_requested_bpc = val; + } else if (property == connector->privacy_screen_sw_state_property) { + state->privacy_screen_sw_state = val; } else if (connector->funcs->atomic_set_property) { return connector->funcs->atomic_set_property(connector, state, property, val); @@ -842,6 +844,10 @@ drm_atomic_connector_get_property(struct drm_connector *connector, *val = 0; } else if (property == connector->max_bpc_property) { *val = state->max_requested_bpc; + } else if (property == connector->privacy_screen_sw_state_property) { + *val = state->privacy_screen_sw_state; + } else if (property == connector->privacy_screen_hw_state_property) { + *val = state->privacy_screen_hw_state; } else if (connector->funcs->atomic_get_property) { return connector->funcs->atomic_get_property(connector, state, property, val); diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 644f0ad10671..01360edc2376 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1186,6 +1186,45 @@ static const struct drm_prop_enum_list dp_colorspaces[] = { * can also expose this property to external outputs, in which case they * must support "None", which should be the default (since external screens * have a built-in scaler). + * + * privacy-screen sw-state, privacy-screen hw-state: + * These 2 optional properties can be used to query the state of the + * electronic privacy screen that is available on some displays; and in + * some cases also control the state. If a driver implements these + * properties then both properties must be present. + * + * "privacy-screen hw-state" is read-only and reflects the actual state + * of the privacy-screen, possible values: "Enabled", "Disabled, + * "Enabled, locked", "Disabled, locked". The locked states indicate + * that the state cannot be changed through the DRM API. E.g. there + * might be devices where the firmware-setup options, or a hardware + * slider-switch, offer always on / off modes. May be add: "This is what the userspace tools must use to query and report the actual status at the moment, if needed" Thank you, suggestions for improving the doc are always very welcome, so I have tried adding this, both as is and with slightly changed wording. But it always feels like it is just repeating earlier info. To me the "reflect the actual state" from the beginning of the paragraph makes it abundantly clear that this indeed is what userspace should use to get, well, the actual state. + * + * "privacy-screen sw-state" can be set to change the privacy-screen state + * when not locked. In this case the driver must update the hw-state + * property to reflect the new state on completion of the commit of the + * sw-state property. Setting the sw-state property when the hw-state is + * locked must be interpreted by the driver as a
[PATCH v2 07/15] drm/mgag200: Set pitch in a separate helper function
The framebuffer's pitch is now set in mgag200_set_offset(). v2: * move offset and bpp-shift calculation into helper functions * use u8 instead of uint8_t * add MGAREG_CRTCEXT0_OFFSET_MASK Signed-off-by: Thomas Zimmermann Tested-by: John Donnelly --- drivers/gpu/drm/mgag200/mgag200_mode.c | 57 +++--- drivers/gpu/drm/mgag200/mgag200_reg.h | 2 + 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 4dba0a379c263..dee7838d7d368 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -1002,6 +1002,48 @@ static void mgag200_set_mode_regs(struct mga_device *mdev, mga_crtc_set_plls(mdev, mode->clock); } +static u8 mgag200_get_bpp_shift(struct mga_device *mdev, + const struct drm_format_info *format) +{ + return mdev->bpp_shifts[format->cpp[0] - 1]; +} + +/* + * Calculates the HW offset value from the framebuffer's pitch. The + * offset is a multiple of the pixel size and depends on the display + * format. + */ +static u32 mgag200_calculate_offset(struct mga_device *mdev, + const struct drm_framebuffer *fb) +{ + u32 offset = fb->pitches[0] / fb->format->cpp[0]; + u8 bppshift = mgag200_get_bpp_shift(mdev, fb->format); + + if (fb->format->cpp[0] * 8 == 24) + offset = (offset * 3) >> (4 - bppshift); + else + offset = offset >> (4 - bppshift); + + return offset; +} + +static void mgag200_set_offset(struct mga_device *mdev, + const struct drm_framebuffer *fb) +{ + u8 crtc13, crtcext0; + u32 offset = mgag200_calculate_offset(mdev, fb); + + RREG_ECRT(0, crtcext0); + + crtc13 = offset & 0xff; + + crtcext0 &= ~MGAREG_CRTCEXT0_OFFSET_MASK; + crtcext0 |= (offset >> 4) & MGAREG_CRTCEXT0_OFFSET_MASK; + + WREG_CRT(0x13, crtc13); + WREG_ECRT(0x00, crtcext0); +} + static int mga_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode, @@ -1010,7 +1052,6 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, struct drm_device *dev = crtc->dev; struct mga_device *mdev = to_mga_device(dev); const struct drm_framebuffer *fb = crtc->primary->fb; - int pitch; int option = 0, option2 = 0; int i; unsigned char misc = 0; @@ -1121,12 +1162,6 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, WREG_SEQ(3, 0); WREG_SEQ(4, 0xe); - pitch = fb->pitches[0] / fb->format->cpp[0]; - if (fb->format->cpp[0] * 8 == 24) - pitch = (pitch * 3) >> (4 - bppshift); - else - pitch = pitch >> (4 - bppshift); - WREG_GFX(0, 0); WREG_GFX(1, 0); WREG_GFX(2, 0); @@ -1143,20 +1178,15 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, WREG_CRT(13, 0); WREG_CRT(14, 0); WREG_CRT(15, 0); - WREG_CRT(19, pitch & 0xFF); - - ext_vga[0] = 0; /* TODO interlace */ - ext_vga[0] |= (pitch & 0x300) >> 4; if (fb->format->cpp[0] * 8 == 24) ext_vga[3] = (((1 << bppshift) * 3) - 1) | 0x80; else ext_vga[3] = ((1 << bppshift) - 1) | 0x80; ext_vga[4] = 0; - WREG_ECRT(0, ext_vga[0]); WREG_ECRT(3, ext_vga[3]); WREG_ECRT(4, ext_vga[4]); @@ -1170,8 +1200,6 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, WREG_ECRT(6, 0); } - WREG_ECRT(0, ext_vga[0]); - misc = RREG8(MGA_MISC_IN); misc |= MGAREG_MISC_IOADSEL | MGAREG_MISC_RAMMAPEN | @@ -1179,6 +1207,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, WREG8(MGA_MISC_OUT, misc); mga_crtc_do_set_base(mdev, fb, old_fb); + mgag200_set_offset(mdev, fb); mgag200_set_mode_regs(mdev, mode); diff --git a/drivers/gpu/drm/mgag200/mgag200_reg.h b/drivers/gpu/drm/mgag200/mgag200_reg.h index 0ba6e15e97106..cd08dee29b06f 100644 --- a/drivers/gpu/drm/mgag200/mgag200_reg.h +++ b/drivers/gpu/drm/mgag200/mgag200_reg.h @@ -240,6 +240,8 @@ #define MGAREG_CRTCEXT_INDEX 0x1fde #define MGAREG_CRTCEXT_DATA0x1fdf +#define MGAREG_CRTCEXT0_OFFSET_MASKGENMASK(5, 4) + /* Cursor X and Y position */ #define MGA_CURPOSXL 0x3c0c #define MGA_CURPOSXH 0x3c0d -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 13/15] drm/mgag200: Use simple-display data structures
The MGA CRTC data structure struct mga_crtc contains unused additional fields; so it can removed. The standard DRM CRTC and encoder structures are embedded now in struct drm_simple_display_pipe. Done in preparation of converting mgag200 to simple KMS helpers. Signed-off-by: Thomas Zimmermann Tested-by: John Donnelly Acked-by: Sam Ravnborg --- drivers/gpu/drm/mgag200/mgag200_drv.h | 11 ++ drivers/gpu/drm/mgag200/mgag200_mode.c | 28 ++ 2 files changed, 8 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index 0cf498d1e900c..2392baff618aa 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -19,6 +19,7 @@ #include #include #include +#include #include "mgag200_reg.h" @@ -105,16 +106,8 @@ #define MATROX_DPMS_CLEARED (-1) -#define to_mga_crtc(x) container_of(x, struct mga_crtc, base) #define to_mga_connector(x) container_of(x, struct mga_connector, base) -struct mga_crtc { - struct drm_crtc base; - u8 lut_r[256], lut_g[256], lut_b[256]; - int last_dpms; - bool enabled; -}; - struct mga_i2c_chan { struct i2c_adapter adapter; struct drm_device *dev; @@ -175,7 +168,7 @@ struct mga_device { u32 unique_rev_id; struct mga_connector connector; - struct drm_encoder encoder; + struct drm_simple_display_pipe display_pipe; }; static inline struct mga_device *to_mga_device(struct drm_device *dev) diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index d6f9763a4a450..00bbc1f9b7db3 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -1475,15 +1475,6 @@ static int mga_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, return 0; } -/* Simple cleanup function */ -static void mga_crtc_destroy(struct drm_crtc *crtc) -{ - struct mga_crtc *mga_crtc = to_mga_crtc(crtc); - - drm_crtc_cleanup(crtc); - kfree(mga_crtc); -} - static void mga_crtc_disable(struct drm_crtc *crtc) { DRM_DEBUG_KMS("\n"); @@ -1501,7 +1492,7 @@ static void mga_crtc_disable(struct drm_crtc *crtc) static const struct drm_crtc_funcs mga_crtc_funcs = { .gamma_set = mga_crtc_gamma_set, .set_config = drm_crtc_helper_set_config, - .destroy = mga_crtc_destroy, + .destroy = drm_crtc_cleanup, }; static const struct drm_crtc_helper_funcs mga_helper_funcs = { @@ -1517,20 +1508,13 @@ static const struct drm_crtc_helper_funcs mga_helper_funcs = { static void mga_crtc_init(struct mga_device *mdev) { struct drm_device *dev = mdev->dev; - struct mga_crtc *mga_crtc; - - mga_crtc = kzalloc(sizeof(struct mga_crtc) + - (MGAG200FB_CONN_LIMIT * sizeof(struct drm_connector *)), - GFP_KERNEL); - - if (mga_crtc == NULL) - return; + struct drm_crtc *crtc = >display_pipe.crtc; - drm_crtc_init(dev, _crtc->base, _crtc_funcs); + drm_crtc_init(dev, crtc, _crtc_funcs); - drm_mode_crtc_set_gamma_size(_crtc->base, MGAG200_LUT_SIZE); + drm_mode_crtc_set_gamma_size(crtc, MGAG200_LUT_SIZE); - drm_crtc_helper_add(_crtc->base, _helper_funcs); + drm_crtc_helper_add(crtc, _helper_funcs); } /* @@ -1718,7 +1702,7 @@ static unsigned int mgag200_preferred_depth(struct mga_device *mdev) int mgag200_modeset_init(struct mga_device *mdev) { struct drm_device *dev = mdev->dev; - struct drm_encoder *encoder = >encoder; + struct drm_encoder *encoder = >display_pipe.encoder; struct drm_connector *connector = >connector.base; int ret; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 01/15] drm/mgag200: Remove HW cursor
The HW cursor of Matrox G200 cards only supports a 16-color palette format. Univeral planes require at least ARGB or a similar component- based format, so remove the HW cursor. Alternatively, the driver could dither a cursor image from ARGB to 16 colors. But this does not produce pleasent-looking results in general, so it's useless for modern compositors. Without HW support, compositors will use software rendering. Signed-off-by: Thomas Zimmermann Tested-by: John Donnelly Acked-by: Sam Ravnborg --- drivers/gpu/drm/mgag200/Makefile | 2 +- drivers/gpu/drm/mgag200/mgag200_drv.h | 13 - drivers/gpu/drm/mgag200/mgag200_main.c | 5 - drivers/gpu/drm/mgag200/mgag200_mode.c | 2 -- 4 files changed, 1 insertion(+), 21 deletions(-) diff --git a/drivers/gpu/drm/mgag200/Makefile b/drivers/gpu/drm/mgag200/Makefile index 04b281bcf6558..63403133638a3 100644 --- a/drivers/gpu/drm/mgag200/Makefile +++ b/drivers/gpu/drm/mgag200/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only -mgag200-y := mgag200_main.o mgag200_mode.o mgag200_cursor.o \ +mgag200-y := mgag200_main.o mgag200_mode.o \ mgag200_drv.o mgag200_i2c.o mgag200_ttm.o obj-$(CONFIG_DRM_MGAG200) += mgag200.o diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index d9b7e96b214f8..bc372c2ec79e9 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -116,11 +116,6 @@ struct mga_connector { struct mga_i2c_chan *i2c; }; -struct mga_cursor { - struct drm_gem_vram_object *gbo[2]; - unsigned int next_index; -}; - struct mga_mc { resource_size_t vram_size; resource_size_t vram_base; @@ -156,8 +151,6 @@ struct mga_device { struct mga_mc mc; - struct mga_cursor cursor; - size_t vram_fb_available; boolsuspended; @@ -207,10 +200,4 @@ int mgag200_mm_init(struct mga_device *mdev); void mgag200_mm_fini(struct mga_device *mdev); int mgag200_mmap(struct file *filp, struct vm_area_struct *vma); -int mgag200_cursor_init(struct mga_device *mdev); -void mgag200_cursor_fini(struct mga_device *mdev); -int mgag200_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, - uint32_t handle, uint32_t width, uint32_t height); -int mgag200_crtc_cursor_move(struct drm_crtc *crtc, int x, int y); - #endif /* __MGAG200_DRV_H__ */ diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c index 86df799fd38c5..3298eff7bd1b4 100644 --- a/drivers/gpu/drm/mgag200/mgag200_main.c +++ b/drivers/gpu/drm/mgag200/mgag200_main.c @@ -135,10 +135,6 @@ int mgag200_driver_load(struct drm_device *dev, unsigned long flags) goto err_mgag200_mm_fini; } - ret = mgag200_cursor_init(mdev); - if (ret) - drm_err(dev, "Could not initialize cursors. Not doing hardware cursors.\n"); - return 0; err_mgag200_mm_fini: @@ -154,7 +150,6 @@ void mgag200_driver_unload(struct drm_device *dev) if (mdev == NULL) return; - mgag200_cursor_fini(mdev); mgag200_mm_fini(mdev); dev->dev_private = NULL; } diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 5f4ac36a97760..c68ed8b6faf9b 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -1412,8 +1412,6 @@ static void mga_crtc_disable(struct drm_crtc *crtc) /* These provide the minimum set of functions required to handle a CRTC */ static const struct drm_crtc_funcs mga_crtc_funcs = { - .cursor_set = mgag200_crtc_cursor_set, - .cursor_move = mgag200_crtc_cursor_move, .gamma_set = mga_crtc_gamma_set, .set_config = drm_crtc_helper_set_config, .destroy = mga_crtc_destroy, -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 06/15] drm/mgag200: Update mode registers after plane registers
Setting the plane registers first and the mode registers afterwards reproduces the sequence used by atomic helpers. Done in preparation of switching to simple KMS helpers. Signed-off-by: Thomas Zimmermann Tested-by: John Donnelly Acked-by: Sam Ravnborg --- drivers/gpu/drm/mgag200/mgag200_mode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 2007d7a4754ac..4dba0a379c263 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -1145,8 +1145,6 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, WREG_CRT(15, 0); WREG_CRT(19, pitch & 0xFF); - mgag200_set_mode_regs(mdev, mode); - ext_vga[0] = 0; /* TODO interlace */ @@ -1182,6 +1180,8 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, mga_crtc_do_set_base(mdev, fb, old_fb); + mgag200_set_mode_regs(mdev, mode); + /* reset tagfifo */ if (mdev->type == G200_ER) { u32 mem_ctl = RREG32(MGAREG_MEMCTL); -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 02/15] drm/mgag200: Clean up mga_set_start_address()
All register names and fields are now named according to the MGA programming manuals. The function doesn't need the CRTC, so callers pass in the device structure directly. The logging now uses device-specific macros. v2: * use to_mga_device() * use MiB instead of MB * replace empty while loop with do-while, fixes checkpatch warning * replace uint{8,32}_t with u{8,32} Signed-off-by: Thomas Zimmermann Tested-by: John Donnelly --- drivers/gpu/drm/mgag200/mgag200_drv.h | 5 ++ drivers/gpu/drm/mgag200/mgag200_mode.c | 82 +++--- 2 files changed, 53 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index bc372c2ec79e9..1963876ef3b8c 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -61,6 +61,11 @@ WREG8(MGAREG_CRTC_DATA, v); \ } while (0) \ +#define RREG_ECRT(reg, v) \ + do {\ + WREG8(MGAREG_CRTCEXT_INDEX, reg); \ + v = RREG8(MGAREG_CRTCEXT_DATA); \ + } while (0) \ #define WREG_ECRT(reg, v) \ do {\ diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index c68ed8b6faf9b..80a3a805c0c4e 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -819,49 +819,53 @@ static void mga_g200wb_commit(struct drm_crtc *crtc) } /* - This is how the framebuffer base address is stored in g200 cards: - * Assume @offset is the gpu_addr variable of the framebuffer object - * Then addr is the number of _pixels_ (not bytes) from the start of - VRAM to the first pixel we want to display. (divided by 2 for 32bit - framebuffers) - * addr is stored in the CRTCEXT0, CRTCC and CRTCD registers - addr<20> -> CRTCEXT0<6> - addr<19-16> -> CRTCEXT0<3-0> - addr<15-8> -> CRTCC<7-0> - addr<7-0> -> CRTCD<7-0> - CRTCEXT0 has to be programmed last to trigger an update and make the - new addr variable take effect. + * This is how the framebuffer base address is stored in g200 cards: + * * Assume @offset is the gpu_addr variable of the framebuffer object + * * Then addr is the number of _pixels_ (not bytes) from the start of + * VRAM to the first pixel we want to display. (divided by 2 for 32bit + * framebuffers) + * * addr is stored in the CRTCEXT0, CRTCC and CRTCD registers + * addr<20> -> CRTCEXT0<6> + * addr<19-16> -> CRTCEXT0<3-0> + * addr<15-8> -> CRTCC<7-0> + * addr<7-0> -> CRTCD<7-0> + * + * CRTCEXT0 has to be programmed last to trigger an update and make the + * new addr variable take effect. */ -static void mga_set_start_address(struct drm_crtc *crtc, unsigned offset) +static void mgag200_set_startadd(struct mga_device *mdev, +unsigned long offset) { - struct mga_device *mdev = to_mga_device(crtc->dev); - u32 addr; - int count; - u8 crtcext0; + struct drm_device *dev = mdev->dev; + u32 startadd; + u8 crtcc, crtcd, crtcext0; - while (RREG8(0x1fda) & 0x08); - while (!(RREG8(0x1fda) & 0x08)); + startadd = offset / 8; - count = RREG8(MGAREG_VCOUNT) + 2; - while (RREG8(MGAREG_VCOUNT) < count); - - WREG8(MGAREG_CRTCEXT_INDEX, 0); - crtcext0 = RREG8(MGAREG_CRTCEXT_DATA); - crtcext0 &= 0xB0; - addr = offset / 8; - /* Can't store addresses any higher than that... - but we also don't have more than 16MB of memory, so it should be fine. */ - WARN_ON(addr > 0x1f); - crtcext0 |= (!!(addr & (1<<20)))<<6; - WREG_CRT(0x0d, (u8)(addr & 0xff)); - WREG_CRT(0x0c, (u8)(addr >> 8) & 0xff); - WREG_ECRT(0x0, ((u8)(addr >> 16) & 0xf) | crtcext0); + /* +* Can't store addresses any higher than that, but we also +* don't have more than 16 MiB of memory, so it should be fine. +*/ + drm_WARN_ON(dev, startadd > 0x1f); + + RREG_ECRT(0x00, crtcext0); + + crtcc = (startadd >> 8) & 0xff; + crtcd = startadd & 0xff; + crtcext0 &= 0xb0; + crtcext0 |= ((startadd >> 14) & BIT(6)) | + ((startadd >> 16) & 0x0f); + + WREG_CRT(0x0c, crtcc); + WREG_CRT(0x0d, crtcd); + WREG_ECRT(0x00, crtcext0); } static int mga_crtc_do_set_base(struct drm_crtc *crtc, struct drm_framebuffer *fb, int x, int y, int atomic) { + struct mga_device *mdev = to_mga_device(crtc->dev); struct drm_gem_vram_object *gbo; int ret;
[PATCH v2 14/15] drm/mgag200: Convert to simple KMS helper
The mgag200 supports a single pipeline with only a primary plane. It can be converted to simple KMS helpers. This also adds support for atomic modesetting. Wayland compositors, which use pageflip ioctls, can now be used with mgag200. v2: * prepare encoder and CRTC in a separate patch * remove suspend/resume code in a separate patch * don't call set_format_regs() in pipe_update() Signed-off-by: Thomas Zimmermann Tested-by: John Donnelly Acked-by: Sam Ravnborg --- drivers/gpu/drm/mgag200/mgag200_drv.c | 2 +- drivers/gpu/drm/mgag200/mgag200_mode.c | 314 + 2 files changed, 164 insertions(+), 152 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index c2f0e4b40b052..a06ce4198adea 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -140,7 +140,7 @@ int mgag200_driver_dumb_create(struct drm_file *file, } static struct drm_driver driver = { - .driver_features = DRIVER_GEM | DRIVER_MODESET, + .driver_features = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET, .fops = _driver_fops, .name = DRIVER_NAME, .desc = DRIVER_DESC, diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 00bbc1f9b7db3..b50c1beb7b7b9 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -11,10 +11,13 @@ #include #include +#include +#include #include #include #include #include +#include #include #include @@ -30,13 +33,18 @@ static void mga_crtc_load_lut(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; struct mga_device *mdev = to_mga_device(dev); - struct drm_framebuffer *fb = crtc->primary->fb; + struct drm_framebuffer *fb; u16 *r_ptr, *g_ptr, *b_ptr; int i; if (!crtc->enabled) return; + if (!mdev->display_pipe.plane.state) + return; + + fb = mdev->display_pipe.plane.state->fb; + r_ptr = crtc->gamma_store; g_ptr = r_ptr + crtc->gamma_size; b_ptr = g_ptr + crtc->gamma_size; @@ -869,56 +877,6 @@ static void mgag200_set_startadd(struct mga_device *mdev, WREG_ECRT(0x00, crtcext0); } -static int mga_crtc_do_set_base(struct mga_device *mdev, - const struct drm_framebuffer *fb, - const struct drm_framebuffer *old_fb) -{ - struct drm_gem_vram_object *gbo; - int ret; - s64 gpu_addr; - - if (old_fb) { - gbo = drm_gem_vram_of_gem(old_fb->obj[0]); - drm_gem_vram_unpin(gbo); - } - - gbo = drm_gem_vram_of_gem(fb->obj[0]); - - ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM); - if (ret) - return ret; - gpu_addr = drm_gem_vram_offset(gbo); - if (gpu_addr < 0) { - ret = (int)gpu_addr; - goto err_drm_gem_vram_unpin; - } - - mgag200_set_startadd(mdev, (unsigned long)gpu_addr); - - return 0; - -err_drm_gem_vram_unpin: - drm_gem_vram_unpin(gbo); - return ret; -} - -static int mga_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb) -{ - struct drm_device *dev = crtc->dev; - struct mga_device *mdev = dev->dev_private; - struct drm_framebuffer *fb = crtc->primary->fb; - unsigned int count; - - do { } while (RREG8(0x1fda) & 0x08); - do { } while (!(RREG8(0x1fda) & 0x08)); - - count = RREG8(MGAREG_VCOUNT) + 2; - do { } while (RREG8(MGAREG_VCOUNT) < count); - - return mga_crtc_do_set_base(mdev, fb, old_fb); -} - static void mgag200_set_pci_regs(struct mga_device *mdev) { uint32_t option = 0, option2 = 0; @@ -1329,34 +1287,6 @@ static void mgag200_g200ev_set_hiprilvl(struct mga_device *mdev) WREG_ECRT(0x06, 0x00); } -static int mga_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, struct drm_framebuffer *old_fb) -{ - struct drm_device *dev = crtc->dev; - struct mga_device *mdev = to_mga_device(dev); - const struct drm_framebuffer *fb = crtc->primary->fb; - - mgag200_init_regs(mdev); - - mgag200_set_format_regs(mdev, fb); - mga_crtc_do_set_base(mdev, fb, old_fb); - mgag200_set_offset(mdev, fb); - - mgag200_set_mode_regs(mdev, mode); - - if (mdev->type == G200_ER) - mgag200_g200er_reset_tagfifo(mdev); - - if (IS_G200_SE(mdev)) - mgag200_g200se_set_hiprilvl(mdev, mode, fb); - else if (mdev->type == G200_EV) - mgag200_g200ev_set_hiprilvl(mdev); - - return 0; -} - static void
[PATCH v2 15/15] drm/mgag200: Replace VRAM helpers with SHMEM helpers
The VRAM helpers managed the framebuffer memory for mgag200. This came with several problems, as some MGA device require the scanout address to be located at VRAM offset 0. It's incompatible with the page-flip semantics of DRM's atomic modesettting. With atomic modesetting, old and new framebuffers have to be located in VRAM at the same time. So at least one of them has to reside at a non-0 offset. This patch replaces VRAM helpers with SHMEM helpers. GEM SHMEM buffers reside in system memory, and are shadow-copied into VRAM during page flips. The shadow copy always starts at VRAM offset 0. v2: * revert dev->pdev changes Signed-off-by: Thomas Zimmermann Tested-by: John Donnelly --- drivers/gpu/drm/mgag200/Kconfig| 4 +- drivers/gpu/drm/mgag200/mgag200_drv.c | 49 +- drivers/gpu/drm/mgag200/mgag200_drv.h | 5 ++- drivers/gpu/drm/mgag200/mgag200_mode.c | 58 -- drivers/gpu/drm/mgag200/mgag200_ttm.c | 28 +++-- 5 files changed, 56 insertions(+), 88 deletions(-) diff --git a/drivers/gpu/drm/mgag200/Kconfig b/drivers/gpu/drm/mgag200/Kconfig index d60aa4b9ccd47..93be766715c9b 100644 --- a/drivers/gpu/drm/mgag200/Kconfig +++ b/drivers/gpu/drm/mgag200/Kconfig @@ -2,10 +2,8 @@ config DRM_MGAG200 tristate "Kernel modesetting driver for MGA G200 server engines" depends on DRM && PCI && MMU + select DRM_GEM_SHMEM_HELPER select DRM_KMS_HELPER - select DRM_VRAM_HELPER - select DRM_TTM - select DRM_TTM_HELPER help This is a KMS driver for the MGA G200 server chips, it does not support the original MGA G200 or any of the desktop diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index a06ce4198adea..00ddea7d7d270 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -22,15 +22,11 @@ * which then performs further device association and calls our graphics init * functions */ -int mgag200_modeset = -1; +int mgag200_modeset = -1; MODULE_PARM_DESC(modeset, "Disable/Enable modesetting"); module_param_named(modeset, mgag200_modeset, int, 0400); -int mgag200_hw_bug_no_startadd = -1; -MODULE_PARM_DESC(modeset, "HW does not interpret scanout-buffer start address correctly"); -module_param_named(hw_bug_no_startadd, mgag200_hw_bug_no_startadd, int, 0400); - static struct drm_driver driver; static const struct pci_device_id pciidlist[] = { @@ -101,44 +97,6 @@ static void mga_pci_remove(struct pci_dev *pdev) DEFINE_DRM_GEM_FOPS(mgag200_driver_fops); -static bool mgag200_pin_bo_at_0(const struct mga_device *mdev) -{ - if (mgag200_hw_bug_no_startadd > 0) { - DRM_WARN_ONCE("Option hw_bug_no_startradd is enabled. Please " - "report the output of 'lspci -vvnn' to " - " if this " - "option is required to make mgag200 work " - "correctly on your system.\n"); - return true; - } else if (!mgag200_hw_bug_no_startadd) { - return false; - } - return mdev->flags & MGAG200_FLAG_HW_BUG_NO_STARTADD; -} - -int mgag200_driver_dumb_create(struct drm_file *file, - struct drm_device *dev, - struct drm_mode_create_dumb *args) -{ - struct mga_device *mdev = to_mga_device(dev); - unsigned long pg_align; - - if (WARN_ONCE(!dev->vram_mm, "VRAM MM not initialized")) - return -EINVAL; - - pg_align = 0ul; - - /* -* Aligning scanout buffers to the size of the video ram forces -* placement at offset 0. Works around a bug where HW does not -* respect 'startadd' field. -*/ - if (mgag200_pin_bo_at_0(mdev)) - pg_align = PFN_UP(mdev->mc.vram_size); - - return drm_gem_vram_fill_create_dumb(file, dev, pg_align, 0, args); -} - static struct drm_driver driver = { .driver_features = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET, .fops = _driver_fops, @@ -148,10 +106,7 @@ static struct drm_driver driver = { .major = DRIVER_MAJOR, .minor = DRIVER_MINOR, .patchlevel = DRIVER_PATCHLEVEL, - .debugfs_init = drm_vram_mm_debugfs_init, - .dumb_create = mgag200_driver_dumb_create, - .dumb_map_offset = drm_gem_vram_driver_dumb_mmap_offset, - .gem_prime_mmap = drm_gem_prime_mmap, + DRM_GEM_SHMEM_DRIVER_OPS, }; static struct pci_driver mgag200_pci_driver = { diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index 2392baff618aa..d530df25c822d 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include "mgag200_reg.h" @@ -155,7 +155,8 @@ struct mga_device {
[PATCH v2 12/15] drm/mgag200: Remove out-commented suspend/resume helpers
The suspend/resume helpers are unused. Also remove associated state from struct mga_device. Signed-off-by: Thomas Zimmermann Tested-by: John Donnelly Acked-by: Sam Ravnborg --- drivers/gpu/drm/mgag200/mgag200_drv.h | 1 - drivers/gpu/drm/mgag200/mgag200_mode.c | 71 -- 2 files changed, 72 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index cf71a4ec84158..0cf498d1e900c 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -164,7 +164,6 @@ struct mga_device { size_t vram_fb_available; - boolsuspended; enum mga_type type; int has_sdram; diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 199ae08976e16..d6f9763a4a450 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -1357,65 +1357,6 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, return 0; } -#if 0 /* code from mjg to attempt D3 on crtc dpms off - revisit later */ -static int mga_suspend(struct drm_crtc *crtc) -{ - struct mga_crtc *mga_crtc = to_mga_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct mga_device *mdev = dev->dev_private; - struct pci_dev *pdev = dev->pdev; - int option; - - if (mdev->suspended) - return 0; - - WREG_SEQ(1, 0x20); - WREG_ECRT(1, 0x30); - /* Disable the pixel clock */ - WREG_DAC(0x1a, 0x05); - /* Power down the DAC */ - WREG_DAC(0x1e, 0x18); - /* Power down the pixel PLL */ - WREG_DAC(0x1a, 0x0d); - - /* Disable PLLs and clocks */ - pci_read_config_dword(pdev, PCI_MGA_OPTION, ); - option &= ~(0x1F8024); - pci_write_config_dword(pdev, PCI_MGA_OPTION, option); - pci_set_power_state(pdev, PCI_D3hot); - pci_disable_device(pdev); - - mdev->suspended = true; - - return 0; -} - -static int mga_resume(struct drm_crtc *crtc) -{ - struct mga_crtc *mga_crtc = to_mga_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct mga_device *mdev = dev->dev_private; - struct pci_dev *pdev = dev->pdev; - int option; - - if (!mdev->suspended) - return 0; - - pci_set_power_state(pdev, PCI_D0); - pci_enable_device(pdev); - - /* Disable sysclk */ - pci_read_config_dword(pdev, PCI_MGA_OPTION, ); - option &= ~(0x4); - pci_write_config_dword(pdev, PCI_MGA_OPTION, option); - - mdev->suspended = false; - - return 0; -} - -#endif - static void mga_crtc_dpms(struct drm_crtc *crtc, int mode) { struct drm_device *dev = crtc->dev; @@ -1442,11 +1383,6 @@ static void mga_crtc_dpms(struct drm_crtc *crtc, int mode) break; } -#if 0 - if (mode == DRM_MODE_DPMS_OFF) { - mga_suspend(crtc); - } -#endif WREG8(MGAREG_SEQ_INDEX, 0x01); seq1 |= RREG8(MGAREG_SEQ_DATA) & ~0x20; mga_wait_vsync(mdev); @@ -1456,13 +1392,6 @@ static void mga_crtc_dpms(struct drm_crtc *crtc, int mode) WREG8(MGAREG_CRTCEXT_INDEX, 0x01); crtcext1 |= RREG8(MGAREG_CRTCEXT_DATA) & ~0x30; WREG8(MGAREG_CRTCEXT_DATA, crtcext1); - -#if 0 - if (mode == DRM_MODE_DPMS_ON && mdev->suspended == true) { - mga_resume(crtc); - drm_helper_resume_force_mode(dev); - } -#endif } /* -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 10/15] drm/mgag200: Move hiprilvl setting into separate functions
The hiprivlvl settings are now updated in mgag200_g200se_set_hiprilvl() and mgag200_g200ev_set_hiprilvl(). v2: * replace uint8_t with u8 Signed-off-by: Thomas Zimmermann Tested-by: John Donnelly Acked-by: Sam Ravnborg --- drivers/gpu/drm/mgag200/mgag200_mode.c | 98 ++ 1 file changed, 54 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 68ae604926757..46122fa319889 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -1133,6 +1133,56 @@ static void mgag200_g200er_reset_tagfifo(struct mga_device *mdev) WREG_SEQ(0x01, seq1); } +static void mgag200_g200se_set_hiprilvl(struct mga_device *mdev, + const struct drm_display_mode *mode, + const struct drm_framebuffer *fb) +{ + unsigned int hiprilvl; + u8 crtcext6; + + if (mdev->unique_rev_id >= 0x04) { + hiprilvl = 0; + } else if (mdev->unique_rev_id >= 0x02) { + unsigned int bpp; + unsigned long mb; + + if (fb->format->cpp[0] * 8 > 16) + bpp = 32; + else if (fb->format->cpp[0] * 8 > 8) + bpp = 16; + else + bpp = 8; + + mb = (mode->clock * bpp) / 1000; + if (mb > 3100) + hiprilvl = 0; + else if (mb > 2600) + hiprilvl = 1; + else if (mb > 1900) + hiprilvl = 2; + else if (mb > 1160) + hiprilvl = 3; + else if (mb > 440) + hiprilvl = 4; + else + hiprilvl = 5; + + } else if (mdev->unique_rev_id >= 0x01) { + hiprilvl = 3; + } else { + hiprilvl = 4; + } + + crtcext6 = hiprilvl; /* implicitly sets maxhipri to 0 */ + + WREG_ECRT(0x06, crtcext6); +} + +static void mgag200_g200ev_set_hiprilvl(struct mga_device *mdev) +{ + WREG_ECRT(0x06, 0x00); +} + static int mga_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode, @@ -1251,10 +1301,6 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, if (mdev->type == G200_EW3) WREG_ECRT(0x34, 0x5); - if (mdev->type == G200_EV) { - WREG_ECRT(6, 0); - } - misc = RREG8(MGA_MISC_IN); misc |= MGAREG_MISC_IOADSEL | MGAREG_MISC_RAMMAPEN | @@ -1270,47 +1316,11 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, if (mdev->type == G200_ER) mgag200_g200er_reset_tagfifo(mdev); + if (IS_G200_SE(mdev)) + mgag200_g200se_set_hiprilvl(mdev, mode, fb); + else if (mdev->type == G200_EV) + mgag200_g200ev_set_hiprilvl(mdev); - if (IS_G200_SE(mdev)) { - if (mdev->unique_rev_id >= 0x04) { - WREG8(MGAREG_CRTCEXT_INDEX, 0x06); - WREG8(MGAREG_CRTCEXT_DATA, 0); - } else if (mdev->unique_rev_id >= 0x02) { - u8 hi_pri_lvl; - u32 bpp; - u32 mb; - - if (fb->format->cpp[0] * 8 > 16) - bpp = 32; - else if (fb->format->cpp[0] * 8 > 8) - bpp = 16; - else - bpp = 8; - - mb = (mode->clock * bpp) / 1000; - if (mb > 3100) - hi_pri_lvl = 0; - else if (mb > 2600) - hi_pri_lvl = 1; - else if (mb > 1900) - hi_pri_lvl = 2; - else if (mb > 1160) - hi_pri_lvl = 3; - else if (mb > 440) - hi_pri_lvl = 4; - else - hi_pri_lvl = 5; - - WREG8(MGAREG_CRTCEXT_INDEX, 0x06); - WREG8(MGAREG_CRTCEXT_DATA, hi_pri_lvl); - } else { - WREG8(MGAREG_CRTCEXT_INDEX, 0x06); - if (mdev->unique_rev_id >= 0x01) - WREG8(MGAREG_CRTCEXT_DATA, 0x03); - else - WREG8(MGAREG_CRTCEXT_DATA, 0x04); - } - } return 0; } -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 09/15] drm/mgag200: Move TAGFIFO reset into separate function
The TAGFIFO state is now reset in mgag200_g200er_reset_tagfifo(). v2: * define MGAREG_SEQ1_SCROFF Signed-off-by: Thomas Zimmermann Tested-by: John Donnelly Acked-by: Sam Ravnborg --- drivers/gpu/drm/mgag200/mgag200_drv.h | 6 drivers/gpu/drm/mgag200/mgag200_mode.c | 45 +- drivers/gpu/drm/mgag200/mgag200_reg.h | 3 ++ 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index 1963876ef3b8c..cf71a4ec84158 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -49,6 +49,12 @@ WREG8(ATTR_DATA, v);\ } while (0) \ +#define RREG_SEQ(reg, v) \ + do {\ + WREG8(MGAREG_SEQ_INDEX, reg); \ + v = RREG8(MGAREG_SEQ_DATA); \ + } while (0) \ + #define WREG_SEQ(reg, v) \ do {\ WREG8(MGAREG_SEQ_INDEX, reg); \ diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 38556f57ad218..68ae604926757 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -1106,6 +1106,33 @@ static void mgag200_set_format_regs(struct mga_device *mdev, WREG_ECRT(3, crtcext3); } +static void mgag200_g200er_reset_tagfifo(struct mga_device *mdev) +{ + static uint32_t RESET_FLAG = 0x0020; /* undocumented magic value */ + u8 seq1; + u32 memctl; + + /* screen off */ + RREG_SEQ(0x01, seq1); + seq1 |= MGAREG_SEQ1_SCROFF; + WREG_SEQ(0x01, seq1); + + memctl = RREG32(MGAREG_MEMCTL); + + memctl |= RESET_FLAG; + WREG32(MGAREG_MEMCTL, memctl); + + udelay(1000); + + memctl &= ~RESET_FLAG; + WREG32(MGAREG_MEMCTL, memctl); + + /* screen on */ + RREG_SEQ(0x01, seq1); + seq1 &= ~MGAREG_SEQ1_SCROFF; + WREG_SEQ(0x01, seq1); +} + static int mga_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode, @@ -1240,22 +1267,8 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, mgag200_set_mode_regs(mdev, mode); - /* reset tagfifo */ - if (mdev->type == G200_ER) { - u32 mem_ctl = RREG32(MGAREG_MEMCTL); - u8 seq1; - - /* screen off */ - WREG8(MGAREG_SEQ_INDEX, 0x01); - seq1 = RREG8(MGAREG_SEQ_DATA) | 0x20; - WREG8(MGAREG_SEQ_DATA, seq1); - - WREG32(MGAREG_MEMCTL, mem_ctl | 0x0020); - udelay(1000); - WREG32(MGAREG_MEMCTL, mem_ctl & ~0x0020); - - WREG8(MGAREG_SEQ_DATA, seq1 & ~0x20); - } + if (mdev->type == G200_ER) + mgag200_g200er_reset_tagfifo(mdev); if (IS_G200_SE(mdev)) { diff --git a/drivers/gpu/drm/mgag200/mgag200_reg.h b/drivers/gpu/drm/mgag200/mgag200_reg.h index cd08dee29b06f..29f7194faadc0 100644 --- a/drivers/gpu/drm/mgag200/mgag200_reg.h +++ b/drivers/gpu/drm/mgag200/mgag200_reg.h @@ -235,6 +235,9 @@ /* MMIO VGA registers */ #define MGAREG_SEQ_INDEX 0x1fc4 #define MGAREG_SEQ_DATA0x1fc5 + +#define MGAREG_SEQ1_SCROFF BIT(5) + #define MGAREG_CRTC_INDEX 0x1fd4 #define MGAREG_CRTC_DATA 0x1fd5 #define MGAREG_CRTCEXT_INDEX 0x1fde -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 08/15] drm/mgag200: Set primary plane's format in separate helper function
The primary plane's format registers are now updated in a mgag200_set_format_regs(). v2: * get bpp shift from helper function * replace uint8_t with u8 Signed-off-by: Thomas Zimmermann Tested-by: John Donnelly --- drivers/gpu/drm/mgag200/mgag200_mode.c | 109 - 1 file changed, 69 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index dee7838d7d368..38556f57ad218 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -1044,6 +1044,68 @@ static void mgag200_set_offset(struct mga_device *mdev, WREG_ECRT(0x00, crtcext0); } +static void mgag200_set_format_regs(struct mga_device *mdev, + const struct drm_framebuffer *fb) +{ + struct drm_device *dev = mdev->dev; + const struct drm_format_info *format = fb->format; + unsigned int bpp, bppshift, scale; + u8 crtcext3, xmulctrl; + + bpp = format->cpp[0] * 8; + + bppshift = mgag200_get_bpp_shift(mdev, format); + switch (bpp) { + case 24: + scale = ((1 << bppshift) * 3) - 1; + break; + default: + scale = (1 << bppshift) - 1; + break; + } + + RREG_ECRT(3, crtcext3); + + switch (bpp) { + case 8: + xmulctrl = MGA1064_MUL_CTL_8bits; + break; + case 16: + if (format->depth == 15) + xmulctrl = MGA1064_MUL_CTL_15bits; + else + xmulctrl = MGA1064_MUL_CTL_16bits; + break; + case 24: + xmulctrl = MGA1064_MUL_CTL_24bits; + break; + case 32: + xmulctrl = MGA1064_MUL_CTL_32_24bits; + break; + default: + /* BUG: We should have caught this problem already. */ + drm_WARN_ON(dev, "invalid format depth\n"); + return; + } + + crtcext3 &= ~GENMASK(2, 0); + crtcext3 |= scale; + + WREG_DAC(MGA1064_MUL_CTL, xmulctrl); + + WREG_GFX(0, 0x00); + WREG_GFX(1, 0x00); + WREG_GFX(2, 0x00); + WREG_GFX(3, 0x00); + WREG_GFX(4, 0x00); + WREG_GFX(5, 0x40); + WREG_GFX(6, 0x05); + WREG_GFX(7, 0x0f); + WREG_GFX(8, 0x0f); + + WREG_ECRT(3, crtcext3); +} + static int mga_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode, @@ -1055,8 +1117,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, int option = 0, option2 = 0; int i; unsigned char misc = 0; - unsigned char ext_vga[6]; - u8 bppshift; + u8 crtcext3, crtcext4; static unsigned char dacvalue[] = { /* 0x00: */0,0,0,0,0,0, 0x00,0, @@ -1071,8 +1132,6 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, /* 0x48: */0,0,0,0,0,0,0,0 }; - bppshift = mdev->bpp_shifts[fb->format->cpp[0] - 1]; - switch (mdev->type) { case G200_SE_A: case G200_SE_B: @@ -,24 +1170,6 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, break; } - switch (fb->format->cpp[0] * 8) { - case 8: - dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_8bits; - break; - case 16: - if (fb->format->depth == 15) - dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_15bits; - else - dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_16bits; - break; - case 24: - dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_24bits; - break; - case 32: - dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_32_24bits; - break; - } - for (i = 0; i < sizeof(dacvalue); i++) { if ((i <= 0x17) || (i == 0x1b) || @@ -1162,16 +1203,6 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, WREG_SEQ(3, 0); WREG_SEQ(4, 0xe); - WREG_GFX(0, 0); - WREG_GFX(1, 0); - WREG_GFX(2, 0); - WREG_GFX(3, 0); - WREG_GFX(4, 0); - WREG_GFX(5, 0x40); - WREG_GFX(6, 0x5); - WREG_GFX(7, 0xf); - WREG_GFX(8, 0xf); - WREG_CRT(10, 0); WREG_CRT(11, 0); WREG_CRT(12, 0); @@ -1179,16 +1210,13 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, WREG_CRT(14, 0); WREG_CRT(15, 0); - /* TODO interlace */ + RREG_ECRT(0x03, crtcext3); - if (fb->format->cpp[0] * 8 == 24) - ext_vga[3] = (((1 << bppshift) * 3) - 1) | 0x80; - else - ext_vga[3] = ((1 << bppshift) - 1) | 0x80; -
[PATCH v2 04/15] drm/mgag200: Move mode-setting code into separate helper function
The mode-setting code is now located in mgag200_set_mode_regs(), sans a few flags that will be moved in a later patch for clarity. v2: * replace uint8_t with u8 Signed-off-by: Thomas Zimmermann Tested-by: John Donnelly Acked-by: Sam Ravnborg --- drivers/gpu/drm/mgag200/mgag200_mode.c | 140 ++--- 1 file changed, 78 insertions(+), 62 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 9aa6addbbb895..7c41bd43f79e0 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -911,6 +911,79 @@ static int mga_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, return mga_crtc_do_set_base(mdev, fb, old_fb); } +static void mgag200_set_mode_regs(struct mga_device *mdev, + const struct drm_display_mode *mode) +{ + unsigned int hdisplay, hsyncstart, hsyncend, htotal; + unsigned int vdisplay, vsyncstart, vsyncend, vtotal; + u8 misc = 0; + u8 crtcext1, crtcext2, crtcext5; + + hdisplay = mode->hdisplay / 8 - 1; + hsyncstart = mode->hsync_start / 8 - 1; + hsyncend = mode->hsync_end / 8 - 1; + htotal = mode->htotal / 8 - 1; + + /* Work around hardware quirk */ + if ((htotal & 0x07) == 0x06 || (htotal & 0x07) == 0x04) + htotal++; + + vdisplay = mode->vdisplay - 1; + vsyncstart = mode->vsync_start - 1; + vsyncend = mode->vsync_end - 1; + vtotal = mode->vtotal - 2; + + if (mode->flags & DRM_MODE_FLAG_NHSYNC) + misc |= 0x40; + if (mode->flags & DRM_MODE_FLAG_NVSYNC) + misc |= 0x80; + + crtcext1 = (((htotal - 4) & 0x100) >> 8) | + ((hdisplay & 0x100) >> 7) | + ((hsyncstart & 0x100) >> 6) | + (htotal & 0x40); + if (mdev->type == G200_WB || mdev->type == G200_EW3) + crtcext1 |= BIT(7) | /* vrsten */ + BIT(3); /* hrsten */ + + crtcext2 = ((vtotal & 0xc00) >> 10) | + ((vdisplay & 0x400) >> 8) | + ((vdisplay & 0xc00) >> 7) | + ((vsyncstart & 0xc00) >> 5) | + ((vdisplay & 0x400) >> 3); + crtcext5 = 0x00; + + WREG_CRT(0, htotal - 4); + WREG_CRT(1, hdisplay); + WREG_CRT(2, hdisplay); + WREG_CRT(3, (htotal & 0x1F) | 0x80); + WREG_CRT(4, hsyncstart); + WREG_CRT(5, ((htotal & 0x20) << 2) | (hsyncend & 0x1F)); + WREG_CRT(6, vtotal & 0xFF); + WREG_CRT(7, ((vtotal & 0x100) >> 8) | +((vdisplay & 0x100) >> 7) | +((vsyncstart & 0x100) >> 6) | +((vdisplay & 0x100) >> 5) | +((vdisplay & 0x100) >> 4) | /* linecomp */ +((vtotal & 0x200) >> 4) | +((vdisplay & 0x200) >> 3) | +((vsyncstart & 0x200) >> 2)); + WREG_CRT(9, ((vdisplay & 0x200) >> 4) | +((vdisplay & 0x200) >> 3)); + WREG_CRT(16, vsyncstart & 0xFF); + WREG_CRT(17, (vsyncend & 0x0F) | 0x20); + WREG_CRT(18, vdisplay & 0xFF); + WREG_CRT(20, 0); + WREG_CRT(21, vdisplay & 0xFF); + WREG_CRT(22, (vtotal + 1) & 0xFF); + WREG_CRT(23, 0xc3); + WREG_CRT(24, vdisplay & 0xFF); + + WREG_ECRT(0x01, crtcext1); + WREG_ECRT(0x02, crtcext2); + WREG_ECRT(0x05, crtcext5); +} + static int mga_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode, @@ -919,8 +992,6 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, struct drm_device *dev = crtc->dev; struct mga_device *mdev = to_mga_device(dev); const struct drm_framebuffer *fb = crtc->primary->fb; - int hdisplay, hsyncstart, hsyncend, htotal; - int vdisplay, vsyncstart, vsyncend, vtotal; int pitch; int option = 0, option2 = 0; int i; @@ -999,12 +1070,6 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, break; } - if (mode->flags & DRM_MODE_FLAG_NHSYNC) - misc |= 0x40; - if (mode->flags & DRM_MODE_FLAG_NVSYNC) - misc |= 0x80; - - for (i = 0; i < sizeof(dacvalue); i++) { if ((i <= 0x17) || (i == 0x1b) || @@ -1044,20 +1109,6 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, else pitch = pitch >> (4 - bppshift); - hdisplay = mode->hdisplay / 8 - 1; - hsyncstart = mode->hsync_start / 8 - 1; - hsyncend = mode->hsync_end / 8 - 1; - htotal = mode->htotal / 8 - 1; - - /* Work around hardware quirk */ - if ((htotal & 0x07) == 0x06 || (htotal & 0x07) == 0x04) - htotal++; - - vdisplay = mode->vdisplay - 1; - vsyncstart = mode->vsync_start - 1; -
[PATCH v2 11/15] drm/mgag200: Move register initialization into separate function
Registers are initialized with constants. This is now done in mgag200_init_regs(), mgag200_set_dac_regs() and mgag200_set_pci_regs(). Later patches should move these calls from mode setting to device initialization. v2: * replace uint8_t with u8 Signed-off-by: Thomas Zimmermann Tested-by: John Donnelly Acked-by: Sam Ravnborg --- drivers/gpu/drm/mgag200/mgag200_mode.c | 261 ++--- 1 file changed, 147 insertions(+), 114 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 46122fa319889..199ae08976e16 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -919,6 +919,152 @@ static int mga_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, return mga_crtc_do_set_base(mdev, fb, old_fb); } +static void mgag200_set_pci_regs(struct mga_device *mdev) +{ + uint32_t option = 0, option2 = 0; + struct drm_device *dev = mdev->dev; + + switch (mdev->type) { + case G200_SE_A: + case G200_SE_B: + if (mdev->has_sdram) + option = 0x40049120; + else + option = 0x4004d120; + option2 = 0x8000; + break; + case G200_WB: + case G200_EW3: + option = 0x41049120; + option2 = 0xb000; + break; + case G200_EV: + option = 0x0120; + option2 = 0xb000; + break; + case G200_EH: + case G200_EH3: + option = 0x0120; + option2 = 0xb000; + break; + case G200_ER: + break; + } + + if (option) + pci_write_config_dword(dev->pdev, PCI_MGA_OPTION, option); + + if (option2) + pci_write_config_dword(dev->pdev, PCI_MGA_OPTION2, option2); +} + +static void mgag200_set_dac_regs(struct mga_device *mdev) +{ + size_t i; + u8 dacvalue[] = { + /* 0x00: */0,0,0,0,0,0, 0x00,0, + /* 0x08: */0,0,0,0,0,0,0,0, + /* 0x10: */0,0,0,0,0,0,0,0, + /* 0x18: */ 0x00,0, 0xC9, 0xFF, 0xBF, 0x20, 0x1F, 0x20, + /* 0x20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x28: */ 0x00, 0x00, 0x00, 0x00,0,0,0, 0x40, + /* 0x30: */ 0x00, 0xB0, 0x00, 0xC2, 0x34, 0x14, 0x02, 0x83, + /* 0x38: */ 0x00, 0x93, 0x00, 0x77, 0x00, 0x00, 0x00, 0x3A, + /* 0x40: */0,0,0,0,0,0,0,0, + /* 0x48: */0,0,0,0,0,0,0,0 + }; + + switch (mdev->type) { + case G200_SE_A: + case G200_SE_B: + dacvalue[MGA1064_VREF_CTL] = 0x03; + dacvalue[MGA1064_PIX_CLK_CTL] = MGA1064_PIX_CLK_CTL_SEL_PLL; + dacvalue[MGA1064_MISC_CTL] = MGA1064_MISC_CTL_DAC_EN | +MGA1064_MISC_CTL_VGA8 | +MGA1064_MISC_CTL_DAC_RAM_CS; + break; + case G200_WB: + case G200_EW3: + dacvalue[MGA1064_VREF_CTL] = 0x07; + break; + case G200_EV: + dacvalue[MGA1064_PIX_CLK_CTL] = MGA1064_PIX_CLK_CTL_SEL_PLL; + dacvalue[MGA1064_MISC_CTL] = MGA1064_MISC_CTL_VGA8 | +MGA1064_MISC_CTL_DAC_RAM_CS; + break; + case G200_EH: + case G200_EH3: + dacvalue[MGA1064_MISC_CTL] = MGA1064_MISC_CTL_VGA8 | +MGA1064_MISC_CTL_DAC_RAM_CS; + break; + case G200_ER: + break; + } + + for (i = 0; i < ARRAY_SIZE(dacvalue); i++) { + if ((i <= 0x17) || + (i == 0x1b) || + (i == 0x1c) || + ((i >= 0x1f) && (i <= 0x29)) || + ((i >= 0x30) && (i <= 0x37))) + continue; + if (IS_G200_SE(mdev) && + ((i == 0x2c) || (i == 0x2d) || (i == 0x2e))) + continue; + if ((mdev->type == G200_EV || + mdev->type == G200_WB || + mdev->type == G200_EH || + mdev->type == G200_EW3 || + mdev->type == G200_EH3) && + (i >= 0x44) && (i <= 0x4e)) + continue; + + WREG_DAC(i, dacvalue[i]); + } + + if (mdev->type == G200_ER) + WREG_DAC(0x90, 0); +} + +static void mgag200_init_regs(struct mga_device *mdev) +{ + u8 crtcext3, crtcext4, misc; + + mgag200_set_pci_regs(mdev); +
[PATCH v2 00/15] drm/mgag200: Convert to atomic modesetting
This patchset converts mgag200 to atomic modesetting. It uses simple KMS helpers and SHMEM. Patch 1 removes cursor support. The HW cursor is not usable with the way universal planes work. Patches 2 to 11 untangle the existing modesetting code into smaller functions. Specifically, mode setting and plane updates are being separated from each other. Patch 12 to 14 convert mgag200 to simple KMS helpers and enables atomic mode setting. Atomically switching plane framebuffers, requires either source or target buffer to be located at a non-0 offet. As some HW revisions seem to require a framebuffer offset of 0 within the video memory, they do not work with atomic modesetting. To resolve this problem, patch 15 converts mgag200 from VRAM helpers to SHMEM helpers. During plane updates, the content of the SHMEM BO is memcpy'd to VRAM. From my observation, performance is not nuch different from the original code. The patchset has been tested on MGA G200EH hardware. v2: * rebase patchset * replace uint{8,32}_t with u{8,32} through-out patchset * define additional register constants * use helper functions around bpp-shift computations * split conversion patch * cleanups Thomas Zimmermann (15): drm/mgag200: Remove HW cursor drm/mgag200: Clean up mga_set_start_address() drm/mgag200: Clean up mga_crtc_do_set_base() drm/mgag200: Move mode-setting code into separate helper function drm/mgag200: Split MISC register update into PLL selection, SYNC and I/O drm/mgag200: Update mode registers after plane registers drm/mgag200: Set pitch in a separate helper function drm/mgag200: Set primary plane's format in separate helper function drm/mgag200: Move TAGFIFO reset into separate function drm/mgag200: Move hiprilvl setting into separate functions drm/mgag200: Move register initialization into separate function drm/mgag200: Remove out-commented suspend/resume helpers drm/mgag200: Use simple-display data structures drm/mgag200: Convert to simple KMS helper drm/mgag200: Replace VRAM helpers with SHMEM helpers drivers/gpu/drm/mgag200/Kconfig| 4 +- drivers/gpu/drm/mgag200/Makefile | 2 +- drivers/gpu/drm/mgag200/mgag200_drv.c | 51 +- drivers/gpu/drm/mgag200/mgag200_drv.h | 41 +- drivers/gpu/drm/mgag200/mgag200_main.c | 5 - drivers/gpu/drm/mgag200/mgag200_mode.c | 871 ++--- drivers/gpu/drm/mgag200/mgag200_reg.h | 11 +- drivers/gpu/drm/mgag200/mgag200_ttm.c | 28 +- 8 files changed, 528 insertions(+), 485 deletions(-) -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 03/15] drm/mgag200: Clean up mga_crtc_do_set_base()
The function now only takes the device structure, and the old and new framebuffers. Signed-off-by: Thomas Zimmermann Tested-by: John Donnelly Acked-by: Sam Ravnborg --- drivers/gpu/drm/mgag200/mgag200_mode.c | 18 +- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 80a3a805c0c4e..9aa6addbbb895 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -861,21 +861,20 @@ static void mgag200_set_startadd(struct mga_device *mdev, WREG_ECRT(0x00, crtcext0); } -static int mga_crtc_do_set_base(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int x, int y, int atomic) +static int mga_crtc_do_set_base(struct mga_device *mdev, + const struct drm_framebuffer *fb, + const struct drm_framebuffer *old_fb) { - struct mga_device *mdev = to_mga_device(crtc->dev); struct drm_gem_vram_object *gbo; int ret; s64 gpu_addr; - if (!atomic && fb) { - gbo = drm_gem_vram_of_gem(fb->obj[0]); + if (old_fb) { + gbo = drm_gem_vram_of_gem(old_fb->obj[0]); drm_gem_vram_unpin(gbo); } - gbo = drm_gem_vram_of_gem(crtc->primary->fb->obj[0]); + gbo = drm_gem_vram_of_gem(fb->obj[0]); ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM); if (ret) @@ -900,6 +899,7 @@ static int mga_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, { struct drm_device *dev = crtc->dev; struct mga_device *mdev = dev->dev_private; + struct drm_framebuffer *fb = crtc->primary->fb; unsigned int count; do { } while (RREG8(0x1fda) & 0x08); @@ -908,7 +908,7 @@ static int mga_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, count = RREG8(MGAREG_VCOUNT) + 2; do { } while (RREG8(MGAREG_VCOUNT) < count); - return mga_crtc_do_set_base(crtc, old_fb, x, y, 0); + return mga_crtc_do_set_base(mdev, fb, old_fb); } static int mga_crtc_mode_set(struct drm_crtc *crtc, @@ -1150,7 +1150,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, WREG8(MGA_MISC_OUT, misc); - mga_crtc_do_set_base(crtc, old_fb, x, y, 0); + mga_crtc_do_set_base(mdev, fb, old_fb); /* reset tagfifo */ if (mdev->type == G200_ER) { -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 05/15] drm/mgag200: Split MISC register update into PLL selection, SYNC and I/O
Set different fields in MISC in their rsp location in the code. This patch also fixes a bug in the original code where the mode's SYNC flags were never written into the MISC register. v2: * use u8 instead of uint8_t * define MGAREG_MISC_CLK_SEL_MASK Signed-off-by: Thomas Zimmermann Tested-by: John Donnelly --- drivers/gpu/drm/mgag200/mgag200_mode.c | 38 ++ drivers/gpu/drm/mgag200/mgag200_reg.h | 6 +++- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 7c41bd43f79e0..2007d7a4754ac 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -704,6 +704,8 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock) static int mga_crtc_set_plls(struct mga_device *mdev, long clock) { + u8 misc; + switch(mdev->type) { case G200_SE_A: case G200_SE_B: @@ -724,6 +726,12 @@ static int mga_crtc_set_plls(struct mga_device *mdev, long clock) return mga_g200er_set_plls(mdev, clock); break; } + + misc = RREG8(MGA_MISC_IN); + misc &= ~MGAREG_MISC_CLK_SEL_MASK; + misc |= MGAREG_MISC_CLK_SEL_MGA_MSK; + WREG8(MGA_MISC_OUT, misc); + return 0; } @@ -916,8 +924,7 @@ static void mgag200_set_mode_regs(struct mga_device *mdev, { unsigned int hdisplay, hsyncstart, hsyncend, htotal; unsigned int vdisplay, vsyncstart, vsyncend, vtotal; - u8 misc = 0; - u8 crtcext1, crtcext2, crtcext5; + u8 misc, crtcext1, crtcext2, crtcext5; hdisplay = mode->hdisplay / 8 - 1; hsyncstart = mode->hsync_start / 8 - 1; @@ -933,10 +940,17 @@ static void mgag200_set_mode_regs(struct mga_device *mdev, vsyncend = mode->vsync_end - 1; vtotal = mode->vtotal - 2; + misc = RREG8(MGA_MISC_IN); + if (mode->flags & DRM_MODE_FLAG_NHSYNC) - misc |= 0x40; + misc |= MGAREG_MISC_HSYNCPOL; + else + misc &= ~MGAREG_MISC_HSYNCPOL; + if (mode->flags & DRM_MODE_FLAG_NVSYNC) - misc |= 0x80; + misc |= MGAREG_MISC_VSYNCPOL; + else + misc &= ~MGAREG_MISC_VSYNCPOL; crtcext1 = (((htotal - 4) & 0x100) >> 8) | ((hdisplay & 0x100) >> 7) | @@ -982,6 +996,10 @@ static void mgag200_set_mode_regs(struct mga_device *mdev, WREG_ECRT(0x01, crtcext1); WREG_ECRT(0x02, crtcext2); WREG_ECRT(0x05, crtcext5); + + WREG8(MGA_MISC_OUT, misc); + + mga_crtc_set_plls(mdev, mode->clock); } static int mga_crtc_mode_set(struct drm_crtc *crtc, @@ -1140,12 +1158,6 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, ext_vga[3] = ((1 << bppshift) - 1) | 0x80; ext_vga[4] = 0; - /* Set pixel clocks */ - misc = 0x2d; - WREG8(MGA_MISC_OUT, misc); - - mga_crtc_set_plls(mdev, mode->clock); - WREG_ECRT(0, ext_vga[0]); WREG_ECRT(3, ext_vga[3]); WREG_ECRT(4, ext_vga[4]); @@ -1161,9 +1173,11 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, } WREG_ECRT(0, ext_vga[0]); - /* Enable mga pixel clock */ - misc = 0x2d; + misc = RREG8(MGA_MISC_IN); + misc |= MGAREG_MISC_IOADSEL | + MGAREG_MISC_RAMMAPEN | + MGAREG_MISC_HIGH_PG_SEL; WREG8(MGA_MISC_OUT, misc); mga_crtc_do_set_base(mdev, fb, old_fb); diff --git a/drivers/gpu/drm/mgag200/mgag200_reg.h b/drivers/gpu/drm/mgag200/mgag200_reg.h index c096a9d6bcbc1..0ba6e15e97106 100644 --- a/drivers/gpu/drm/mgag200/mgag200_reg.h +++ b/drivers/gpu/drm/mgag200/mgag200_reg.h @@ -16,10 +16,11 @@ * MGA1064SG Mystique register file */ - #ifndef _MGA_REG_H_ #define _MGA_REG_H_ +#include + #defineMGAREG_DWGCTL 0x1c00 #defineMGAREG_MACCESS 0x1c04 /* the following is a mystique only register */ @@ -221,12 +222,15 @@ #define MGAREG_MISC_IOADSEL(0x1 << 0) #define MGAREG_MISC_RAMMAPEN (0x1 << 1) +#define MGAREG_MISC_CLK_SEL_MASK GENMASK(3, 2) #define MGAREG_MISC_CLK_SEL_VGA25 (0x0 << 2) #define MGAREG_MISC_CLK_SEL_VGA28 (0x1 << 2) #define MGAREG_MISC_CLK_SEL_MGA_PIX(0x2 << 2) #define MGAREG_MISC_CLK_SEL_MGA_MSK(0x3 << 2) #define MGAREG_MISC_VIDEO_DIS (0x1 << 4) #define MGAREG_MISC_HIGH_PG_SEL(0x1 << 5) +#define MGAREG_MISC_HSYNCPOL BIT(6) +#define MGAREG_MISC_VSYNCPOL BIT(7) /* MMIO VGA registers */ #define MGAREG_SEQ_INDEX 0x1fc4 -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 2/2] mtd: rawnand: brcmnand: improve hamming oob layout
The current code generates 8 oob sections: S1 1-5 ECC 6-8 S2 9-15 S3 16-21 ECC 22-24 S4 25-31 S5 32-37 ECC 38-40 S6 41-47 S7 48-53 ECC 54-56 S8 57-63 Change it by merging continuous sections: S1 1-5 ECC 6-8 S2 9-21 ECC 22-24 S3 25-37 ECC 38-40 S4 41-53 ECC 54-56 S5 57-63 Fixes: ef5eeea6e911 ("mtd: nand: brcm: switch to mtd_ooblayout_ops") Signed-off-by: Álvaro Fernández Rojas --- v3: invert patch order v2: keep original comment and fix correctly skip byte 6 for small-page nand drivers/mtd/nand/raw/brcmnand/brcmnand.c | 37 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c index 1c1070111ebc..0a1d76fde37b 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c @@ -1100,33 +1100,32 @@ static int brcmnand_hamming_ooblayout_free(struct mtd_info *mtd, int section, struct brcmnand_cfg *cfg = >hwcfg; int sas = cfg->spare_area_size << cfg->sector_size_1k; int sectors = cfg->page_size / (512 << cfg->sector_size_1k); + u32 next; - if (section >= sectors * 2) + if (section > sectors) return -ERANGE; - oobregion->offset = (section / 2) * sas; + next = (section * sas); + if (section < sectors) + next += 6; - if (section & 1) { - oobregion->offset += 9; - oobregion->length = 7; + if (section) { + oobregion->offset = ((section - 1) * sas) + 9; } else { - oobregion->length = 6; - - /* First sector of each page may have BBI */ - if (!section) { - /* -* Small-page NAND use byte 6 for BBI while large-page -* NAND use bytes 0 and 1. -*/ - if (cfg->page_size > 512) { - oobregion->offset += 2; - oobregion->length -= 2; - } else { - oobregion->length--; - } + /* +* Small-page NAND use byte 6 for BBI while large-page +* NAND use bytes 0 and 1. +*/ + if (cfg->page_size > 512) { + oobregion->offset = 2; + } else { + oobregion->offset = 0; + next--; } } + oobregion->length = next - oobregion->offset; + return 0; } -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] dma-buf: fix use-after-free in dmabuffs_dname
Thank you Greg for the comments. On 5/6/2020 2:30 PM, Greg KH wrote: On Wed, May 06, 2020 at 02:00:10PM +0530, Charan Teja Kalla wrote: Thank you Greg for the reply. On 5/5/2020 3:38 PM, Greg KH wrote: On Tue, Apr 28, 2020 at 01:24:02PM +0530, Charan Teja Reddy wrote: The following race occurs while accessing the dmabuf object exported as file: P1 P2 dma_buf_release() dmabuffs_dname() [say lsof reading /proc//fd/] read dmabuf stored in dentry->fsdata Free the dmabuf object Start accessing the dmabuf structure In the above description, the dmabuf object freed in P1 is being accessed from P2 which is resulting into the use-after-free. Below is the dump stack reported. Call Trace: kasan_report+0x12/0x20 __asan_report_load8_noabort+0x14/0x20 dmabuffs_dname+0x4f4/0x560 tomoyo_realpath_from_path+0x165/0x660 tomoyo_get_realpath tomoyo_check_open_permission+0x2a3/0x3e0 tomoyo_file_open tomoyo_file_open+0xa9/0xd0 security_file_open+0x71/0x300 do_dentry_open+0x37a/0x1380 vfs_open+0xa0/0xd0 path_openat+0x12ee/0x3490 do_filp_open+0x192/0x260 do_sys_openat2+0x5eb/0x7e0 do_sys_open+0xf2/0x180 Fixes: bb2bb90 ("dma-buf: add DMA_BUF_SET_NAME ioctls") Nit, please read the documentation for how to do a Fixes: line properly, you need more digits: Fixes: bb2bb9030425 ("dma-buf: add DMA_BUF_SET_NAME ioctls") Will update the patch Reported-by:syzbot+3643a18836bce555b...@syzkaller.appspotmail.com Signed-off-by: Charan Teja Reddy Also, any reason you didn't include the other mailing lists that get_maintainer.pl said to? Really sorry for not sending to complete list. Added now. And finally, no cc: stable in the s-o-b area for an issue that needs to be backported to older kernels? Will update the patch. --- drivers/dma-buf/dma-buf.c | 25 +++-- include/linux/dma-buf.h | 1 + 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 570c923..069d8f78 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -38,18 +39,34 @@ struct dma_buf_list { static struct dma_buf_list db_list; +static void dmabuf_dent_put(struct dma_buf *dmabuf) +{ + if (atomic_dec_and_test(>dent_count)) { + kfree(dmabuf->name); + kfree(dmabuf); + } Why not just use a kref instead of an open-coded atomic value? Kref approach looks cleaner. will update the patch accordingly. +} + static char *dmabuffs_dname(struct dentry *dentry, char *buffer, int buflen) { struct dma_buf *dmabuf; char name[DMA_BUF_NAME_LEN]; size_t ret = 0; + spin_lock(>d_lock); dmabuf = dentry->d_fsdata; + if (!dmabuf || !atomic_add_unless(>dent_count, 1, 0)) { + spin_unlock(>d_lock); + goto out; How can dmabuf not be valid here? And isn't there already a usecount for the buffer? dmabuf exported as file simply relies on that file's refcount, thus fput() releases the dmabuf. We are storing the dmabuf in the dentry->d_fsdata but there is no binding between the dentry and the dmabuf. So, flow will be like 1) P1 calls fput(dmabuf_fd) 2) P2 trying to access the file information of P1. Eg: lsof command trying to list out the dmabuf_fd information using /proc//fd/dmabuf_fd 3) P1 calls the file->f_op->release(dmabuf_fd_file)(ends up in calling dma_buf_release()), thus frees up the dmabuf buffer. 4) P2 access the dmabuf stored in the dentry->d_fsdata which was freed in step 3. So we need to have some refcount mechanism to avoid the use-after-free in step 4. Ok, but watch out, now you have 2 different reference counts for the same structure. Keeping them coordinated is almost always an impossible task so you need to only rely on one. If you can't use the file api, just drop all of the reference counting logic in there and only use the kref one. I feel that changing the refcount logic now to dma-buf objects involve changes in the core dma-buf framework. NO? Instead, how about passing the user passed name directly in the ->d_fsdata inplace of dmabuf object? Because we just need user passed name in the dmabuffs_dname(). With this we can avoid the need for extra refcount on dmabuf. Posted patch-V2: https://lkml.org/lkml/2020/5/8/158 good luck! greg k-h -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 4/5] clk: stm32: Fix stm32f429 ltdc driver loading hang in clk set rate. keep ltdc clk running after kernel startup
From: dillon min as store stm32f4_rcc_register_pll return to the wrong offset of clks, so ltdc gate clk is null. need change clks[PLL_VCO_SAI] to clks[PLL_SAI] add CLK_IGNORE_UNUSED for ltdc to make sure clk not be freed by clk_disable_unused Signed-off-by: dillon min --- drivers/clk/clk-stm32f4.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c index 18117ce..0ba73de 100644 --- a/drivers/clk/clk-stm32f4.c +++ b/drivers/clk/clk-stm32f4.c @@ -129,7 +129,8 @@ static const struct stm32f4_gate_data stm32f429_gates[] __initconst = { { STM32F4_RCC_APB2ENR, 20, "spi5", "apb2_div" }, { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" }, { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, - { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, + { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div", + CLK_IGNORE_UNUSED }, }; static const struct stm32f4_gate_data stm32f469_gates[] __initconst = { @@ -1757,7 +1758,7 @@ static void __init stm32f4_rcc_init(struct device_node *np) clks[PLL_VCO_I2S] = stm32f4_rcc_register_pll("vco_in", >pll_data[1], _clk_lock); - clks[PLL_VCO_SAI] = stm32f4_rcc_register_pll("vco_in", + clks[PLL_SAI] = stm32f4_rcc_register_pll("vco_in", >pll_data[2], _clk_lock); for (n = 0; n < MAX_POST_DIV; n++) { -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
BUG: unable to handle kernel paging request in bitfill_aligned
Hello, syzbot found the following crash on: HEAD commit:1d3962ae Merge tag 'io_uring-5.7-2020-05-08' of git://git... git tree: upstream console output: https://syzkaller.appspot.com/x/log.txt?x=1487425810 kernel config: https://syzkaller.appspot.com/x/.config?x=b0212dbee046bc1f dashboard link: https://syzkaller.appspot.com/bug?extid=00ed1cf405874e141432 compiler: gcc (GCC) 9.0.0 20181231 (experimental) Unfortunately, I don't have any reproducer for this crash yet. IMPORTANT: if you fix the bug, please add the following tag to the commit: Reported-by: syzbot+00ed1cf405874e141...@syzkaller.appspotmail.com BUG: unable to handle page fault for address: 888000cf5080 #PF: supervisor write access in kernel mode #PF: error_code(0x0002) - not-present page PGD d401067 P4D d401067 PUD d402067 PMD cf4063 PTE 0 Oops: 0002 [#1] PREEMPT SMP KASAN CPU: 0 PID: 30473 Comm: syz-executor.4 Not tainted 5.7.0-rc4-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:__writeq arch/x86/include/asm/io.h:98 [inline] RIP: 0010:bitfill_aligned drivers/video/fbdev/core/cfbfillrect.c:64 [inline] RIP: 0010:bitfill_aligned+0xfc/0x200 drivers/video/fbdev/core/cfbfillrect.c:35 Code: fd 44 89 e0 31 d2 bf 07 00 00 00 f7 f5 41 89 c4 89 c6 89 c5 e8 c5 ab b3 fd 41 83 fc 07 76 62 45 89 e7 4c 89 ed e8 44 aa b3 fd <48> 89 5d 00 48 89 5d 08 48 89 5d 10 48 89 5d 18 48 89 5d 20 48 89 RSP: 0018:c90001c474e0 EFLAGS: 00010246 RAX: 0004 RBX: RCX: c90012324000 RDX: 0004 RSI: 83bf846c RDI: 0005 RBP: 888000cf5080 R08: 888056a6a340 R09: 0040 R10: 888218d3331f R11: ed10431a6663 R12: 0030 R13: 888000cf5080 R14: R15: 0030 FS: 7fe0d9986700() GS:8880ae60() knlGS: CS: 0010 DS: ES: CR0: 80050033 CR2: 888000cf5080 CR3: 8ea77000 CR4: 001426f0 DR0: DR1: DR2: DR3: DR6: fffe0ff0 DR7: 0400 Call Trace: cfb_fillrect+0x418/0x7a0 drivers/video/fbdev/core/cfbfillrect.c:327 vga16fb_fillrect+0x68f/0x1960 drivers/video/fbdev/vga16fb.c:951 bit_clear_margins+0x2d5/0x4a0 drivers/video/fbdev/core/bitblit.c:232 fbcon_clear_margins+0x1de/0x240 drivers/video/fbdev/core/fbcon.c:1381 fbcon_switch+0xcde/0x16f0 drivers/video/fbdev/core/fbcon.c:2363 redraw_screen+0x2ae/0x770 drivers/tty/vt/vt.c:1015 fbcon_modechanged+0x581/0x720 drivers/video/fbdev/core/fbcon.c:3000 fbcon_update_vcs+0x3a/0x50 drivers/video/fbdev/core/fbcon.c:3047 fb_set_var+0xad0/0xd40 drivers/video/fbdev/core/fbmem.c:1056 do_fb_ioctl+0x390/0x6e0 drivers/video/fbdev/core/fbmem.c:1109 fb_ioctl+0xdd/0x130 drivers/video/fbdev/core/fbmem.c:1185 vfs_ioctl fs/ioctl.c:47 [inline] ksys_ioctl+0x11a/0x180 fs/ioctl.c:771 __do_sys_ioctl fs/ioctl.c:780 [inline] __se_sys_ioctl fs/ioctl.c:778 [inline] __x64_sys_ioctl+0x6f/0xb0 fs/ioctl.c:778 do_syscall_64+0xf6/0x7d0 arch/x86/entry/common.c:295 entry_SYSCALL_64_after_hwframe+0x49/0xb3 RIP: 0033:0x45c829 Code: 0d b7 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 db b6 fb ff c3 66 2e 0f 1f 84 00 00 00 00 RSP: 002b:7fe0d9985c78 EFLAGS: 0246 ORIG_RAX: 0010 RAX: ffda RBX: 004e4860 RCX: 0045c829 RDX: 2000 RSI: 4601 RDI: 0003 RBP: 0078bf00 R08: R09: R10: R11: 0246 R12: R13: 02f2 R14: 004c54c8 R15: 7fe0d99866d4 Modules linked in: CR2: 888000cf5080 == --- This bug is generated by a bot. It may contain errors. See https://goo.gl/tpsmEJ for more information about syzbot. syzbot engineers can be reached at syzkal...@googlegroups.com. syzbot will keep track of this bug report. See: https://goo.gl/tpsmEJ#status for how to communicate with syzbot. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 6/6] arm64: dts: sdm845: Add "no-hpd" to sn65dsi86 on cheza
On Thu 07 May 14:35 PDT 2020, Douglas Anderson wrote: > We don't have the HPD line hooked up to the bridge chip. Add it as > suggested in the patch ("dt-bindings: drm/bridge: ti-sn65dsi86: > Document no-hpd"). > > NOTE: this patch isn't expected to have any effect but just keeps us > cleaner for the future. Currently the driver in Linux just assumes > that nobody has HPD hooked up. This change allows us to later > implement HPD support in the driver without messing up sdm845-cheza. > > Signed-off-by: Douglas Anderson > Reviewed-by: Stephen Boyd Applied this patch for 5.8 in the Qualcomm SoC tree. Regards, Bjorn > --- > > Changes in v5: None > Changes in v4: None > Changes in v3: None > Changes in v2: > - ("arm64: dts: sdm845: Add "no-hpd" to sn65dsi86 on cheza") new for v2. > > arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi > b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi > index 9070be43a309..5938f8b2aa2f 100644 > --- a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi > +++ b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi > @@ -548,6 +548,8 @@ sn65dsi86_bridge: bridge@2d { > clocks = < RPMH_LN_BB_CLK2>; > clock-names = "refclk"; > > + no-hpd; > + > ports { > #address-cells = <1>; > #size-cells = <0>; > -- > 2.26.2.645.ge9eca65c58-goog > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v7 01/15] PM / EM: change naming convention from 'capacity' to 'performance'
The Energy Model uses concept of performance domain and capacity states in order to calculate power used by CPUs. Change naming convention from capacity to performance state would enable wider usage in future, e.g. upcoming support for other devices other than CPUs. Acked-by: Daniel Lezcano Signed-off-by: Lukasz Luba --- drivers/thermal/cpufreq_cooling.c | 12 ++--- include/linux/energy_model.h | 86 +-- kernel/power/energy_model.c | 44 kernel/sched/topology.c | 20 +++ 4 files changed, 84 insertions(+), 78 deletions(-) diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c index e297e135c031..ad8971e26538 100644 --- a/drivers/thermal/cpufreq_cooling.c +++ b/drivers/thermal/cpufreq_cooling.c @@ -333,18 +333,18 @@ static inline bool em_is_sane(struct cpufreq_cooling_device *cpufreq_cdev, return false; policy = cpufreq_cdev->policy; - if (!cpumask_equal(policy->related_cpus, to_cpumask(em->cpus))) { + if (!cpumask_equal(policy->related_cpus, em_span_cpus(em))) { pr_err("The span of pd %*pbl is misaligned with cpufreq policy %*pbl\n", - cpumask_pr_args(to_cpumask(em->cpus)), + cpumask_pr_args(em_span_cpus(em)), cpumask_pr_args(policy->related_cpus)); return false; } nr_levels = cpufreq_cdev->max_level + 1; - if (em->nr_cap_states != nr_levels) { - pr_err("The number of cap states in pd %*pbl (%u) doesn't match the number of cooling levels (%u)\n", - cpumask_pr_args(to_cpumask(em->cpus)), - em->nr_cap_states, nr_levels); + if (em_pd_nr_perf_states(em) != nr_levels) { + pr_err("The number of performance states in pd %*pbl (%u) doesn't match the number of cooling levels (%u)\n", + cpumask_pr_args(em_span_cpus(em)), + em_pd_nr_perf_states(em), nr_levels); return false; } diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h index ade6486a3382..fe336a9eb5d4 100644 --- a/include/linux/energy_model.h +++ b/include/linux/energy_model.h @@ -10,13 +10,13 @@ #include /** - * em_cap_state - Capacity state of a performance domain + * em_perf_state - Performance state of a performance domain * @frequency: The CPU frequency in KHz, for consistency with CPUFreq * @power: The power consumed by 1 CPU at this level, in milli-watts * @cost: The cost coefficient associated with this level, used during * energy calculation. Equal to: power * max_frequency / frequency */ -struct em_cap_state { +struct em_perf_state { unsigned long frequency; unsigned long power; unsigned long cost; @@ -24,8 +24,8 @@ struct em_cap_state { /** * em_perf_domain - Performance domain - * @table: List of capacity states, in ascending order - * @nr_cap_states: Number of capacity states + * @table: List of performance states, in ascending order + * @nr_perf_states:Number of performance states * @cpus: Cpumask covering the CPUs of the domain * * A "performance domain" represents a group of CPUs whose performance is @@ -34,22 +34,27 @@ struct em_cap_state { * CPUFreq policies. */ struct em_perf_domain { - struct em_cap_state *table; - int nr_cap_states; + struct em_perf_state *table; + int nr_perf_states; unsigned long cpus[]; }; +#define em_span_cpus(em) (to_cpumask((em)->cpus)) + #ifdef CONFIG_ENERGY_MODEL #define EM_CPU_MAX_POWER 0x struct em_data_callback { /** -* active_power() - Provide power at the next capacity state of a CPU -* @power : Active power at the capacity state in mW (modified) -* @freq: Frequency at the capacity state in kHz (modified) +* active_power() - Provide power at the next performance state of +* a CPU +* @power : Active power at the performance state in mW +* (modified) +* @freq: Frequency at the performance state in kHz +* (modified) * @cpu : CPU for which we do this operation * -* active_power() must find the lowest capacity state of 'cpu' above +* active_power() must find the lowest performance state of 'cpu' above * 'freq' and update 'power' and 'freq' to the matching active power * and frequency. * @@ -80,46 +85,46 @@ static inline unsigned long em_pd_energy(struct em_perf_domain *pd, unsigned long max_util, unsigned long sum_util) { unsigned long freq, scale_cpu; - struct em_cap_state *cs; + struct em_perf_state *ps; int i, cpu; /* -* In
[PATCH v7 13/15] thermal: devfreq_cooling: remove old power model and use EM
Remove old power model and use new Energy Model to calculate the power budget. It drops static + dynamic power calculations and power table in order to use Energy Model performance domain data. This model should be easy to use and could find more users. It is also less complicated to setup the needed structures. Signed-off-by: Lukasz Luba --- drivers/thermal/devfreq_cooling.c | 282 +- include/linux/devfreq_cooling.h | 17 -- 2 files changed, 86 insertions(+), 213 deletions(-) diff --git a/drivers/thermal/devfreq_cooling.c b/drivers/thermal/devfreq_cooling.c index c7ffed2d6ee0..79dcef3dbeeb 100644 --- a/drivers/thermal/devfreq_cooling.c +++ b/drivers/thermal/devfreq_cooling.c @@ -41,20 +41,17 @@ static DEFINE_IDA(devfreq_ida); * @cdev: Pointer to associated thermal cooling device. * @devfreq: Pointer to associated devfreq device. * @cooling_state: Current cooling state. - * @power_table: Pointer to table with maximum power draw for each - * cooling state. State is the index into the table, and - * the power is in mW. * @freq_table:Pointer to a table with the frequencies sorted in descending * order. You can index the table by cooling device state - * @freq_table_size: Size of the @freq_table and @power_table - * @power_ops: Pointer to devfreq_cooling_power, used to generate the - * @power_table. + * @max_state: It is the last index, that is, one less than the number of the + * OPPs + * @power_ops: Pointer to devfreq_cooling_power, a more precised model. * @res_util: Resource utilization scaling factor for the power. * It is multiplied by 100 to minimize the error. It is used * for estimation of the power budget instead of using - * 'utilization' (which is 'busy_time / 'total_time'). - * The 'res_util' range is from 100 to (power_table[state] * 100) - * for the corresponding 'state'. + * 'utilization' (which is 'busy_time' / 'total_time'). + * The 'res_util' range is from 100 to power * 100 for the + * corresponding 'state'. * @capped_state: index to cooling state with in dynamic power budget * @req_max_freq: PM QoS request for limiting the maximum frequency * of the devfreq device. @@ -66,9 +63,8 @@ struct devfreq_cooling_device { struct thermal_cooling_device *cdev; struct devfreq *devfreq; unsigned long cooling_state; - u32 *power_table; u32 *freq_table; - size_t freq_table_size; + size_t max_state; struct devfreq_cooling_power *power_ops; u32 res_util; int capped_state; @@ -82,7 +78,7 @@ static int devfreq_cooling_get_max_state(struct thermal_cooling_device *cdev, { struct devfreq_cooling_device *dfc = cdev->devdata; - *state = dfc->freq_table_size - 1; + *state = dfc->max_state; return 0; } @@ -110,10 +106,16 @@ static int devfreq_cooling_set_cur_state(struct thermal_cooling_device *cdev, dev_dbg(dev, "Setting cooling state %lu\n", state); - if (state >= dfc->freq_table_size) + if (state > dfc->max_state) return -EINVAL; - freq = dfc->freq_table[state]; + if (dfc->em) { + /* Energy Model frequencies are in kHz */ + freq = dfc->em->table[dfc->max_state - state].frequency; + freq *= 1000; + } else { + freq = dfc->freq_table[state]; + } dev_pm_qos_update_request(>req_max_freq, DIV_ROUND_UP(freq, HZ_PER_KHZ)); @@ -124,11 +126,11 @@ static int devfreq_cooling_set_cur_state(struct thermal_cooling_device *cdev, } /** - * freq_get_state() - get the cooling state corresponding to a frequency + * freq_get_state() - get the performance index corresponding to a frequency * @dfc: Pointer to devfreq cooling device - * @freq: frequency in Hz + * @freq: frequency in kHz * - * Return: the cooling state associated with the @freq, or + * Return: the performance index associated with the @freq, or * THERMAL_CSTATE_INVALID if it wasn't found. */ static unsigned long @@ -136,8 +138,8 @@ freq_get_state(struct devfreq_cooling_device *dfc, unsigned long freq) { int i; - for (i = 0; i < dfc->freq_table_size; i++) { - if (dfc->freq_table[i] == freq) + for (i = 0; i <= dfc->max_state; i++) { + if (dfc->em->table[i].frequency == freq) return i; } @@ -172,71 +174,15 @@ static unsigned long get_voltage(struct devfreq *df, unsigned long freq) return voltage; } -/** - * get_static_power() - calculate the static power - * @dfc: Pointer to devfreq cooling device - * @freq: Frequency in Hz - * - * Calculate the static power in milliwatts using
[PATCH v7 08/15] OPP: refactor dev_pm_opp_of_register_em() and update related drivers
The Energy Model framework supports not only CPU devices. Drop the CPU specific interface with cpumask and add struct device. Add also a return value, user might use it. This new interface provides easy way to create a simple Energy Model, which then might be used by e.g. thermal subsystem. Acked-by: Daniel Lezcano Signed-off-by: Lukasz Luba --- drivers/cpufreq/cpufreq-dt.c | 2 +- drivers/cpufreq/imx6q-cpufreq.c| 2 +- drivers/cpufreq/mediatek-cpufreq.c | 2 +- drivers/cpufreq/omap-cpufreq.c | 2 +- drivers/cpufreq/qcom-cpufreq-hw.c | 2 +- drivers/cpufreq/scpi-cpufreq.c | 2 +- drivers/cpufreq/vexpress-spc-cpufreq.c | 2 +- drivers/opp/of.c | 71 -- include/linux/pm_opp.h | 15 +- 9 files changed, 65 insertions(+), 35 deletions(-) diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index 26fe8dfb9ce6..f9f03fd49b83 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -275,7 +275,7 @@ static int cpufreq_init(struct cpufreq_policy *policy) policy->cpuinfo.transition_latency = transition_latency; policy->dvfs_possible_from_any_cpu = true; - dev_pm_opp_of_register_em(policy->cpus); + dev_pm_opp_of_register_em(cpu_dev, policy->cpus); return 0; diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c index fdb2bd15..ef7b34c1fd2b 100644 --- a/drivers/cpufreq/imx6q-cpufreq.c +++ b/drivers/cpufreq/imx6q-cpufreq.c @@ -193,7 +193,7 @@ static int imx6q_cpufreq_init(struct cpufreq_policy *policy) policy->clk = clks[ARM].clk; cpufreq_generic_init(policy, freq_table, transition_latency); policy->suspend_freq = max_freq; - dev_pm_opp_of_register_em(policy->cpus); + dev_pm_opp_of_register_em(cpu_dev, policy->cpus); return 0; } diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c index 0c98dd08273d..7d1212c9b7c8 100644 --- a/drivers/cpufreq/mediatek-cpufreq.c +++ b/drivers/cpufreq/mediatek-cpufreq.c @@ -448,7 +448,7 @@ static int mtk_cpufreq_init(struct cpufreq_policy *policy) policy->driver_data = info; policy->clk = info->cpu_clk; - dev_pm_opp_of_register_em(policy->cpus); + dev_pm_opp_of_register_em(info->cpu_dev, policy->cpus); return 0; } diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c index 8d14b42a8c6f..3694bb030df3 100644 --- a/drivers/cpufreq/omap-cpufreq.c +++ b/drivers/cpufreq/omap-cpufreq.c @@ -131,7 +131,7 @@ static int omap_cpu_init(struct cpufreq_policy *policy) /* FIXME: what's the actual transition time? */ cpufreq_generic_init(policy, freq_table, 300 * 1000); - dev_pm_opp_of_register_em(policy->cpus); + dev_pm_opp_of_register_em(mpu_dev, policy->cpus); return 0; } diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c index fc92a8842e25..0a04b6f03b9a 100644 --- a/drivers/cpufreq/qcom-cpufreq-hw.c +++ b/drivers/cpufreq/qcom-cpufreq-hw.c @@ -238,7 +238,7 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) goto error; } - dev_pm_opp_of_register_em(policy->cpus); + dev_pm_opp_of_register_em(cpu_dev, policy->cpus); policy->fast_switch_possible = true; diff --git a/drivers/cpufreq/scpi-cpufreq.c b/drivers/cpufreq/scpi-cpufreq.c index 20d1f85d5f5a..b0f5388b8854 100644 --- a/drivers/cpufreq/scpi-cpufreq.c +++ b/drivers/cpufreq/scpi-cpufreq.c @@ -167,7 +167,7 @@ static int scpi_cpufreq_init(struct cpufreq_policy *policy) policy->fast_switch_possible = false; - dev_pm_opp_of_register_em(policy->cpus); + dev_pm_opp_of_register_em(cpu_dev, policy->cpus); return 0; diff --git a/drivers/cpufreq/vexpress-spc-cpufreq.c b/drivers/cpufreq/vexpress-spc-cpufreq.c index 83c85d3d67e3..4e8b1dee7c9a 100644 --- a/drivers/cpufreq/vexpress-spc-cpufreq.c +++ b/drivers/cpufreq/vexpress-spc-cpufreq.c @@ -450,7 +450,7 @@ static int ve_spc_cpufreq_init(struct cpufreq_policy *policy) policy->freq_table = freq_table[cur_cluster]; policy->cpuinfo.transition_latency = 100; /* 1 ms */ - dev_pm_opp_of_register_em(policy->cpus); + dev_pm_opp_of_register_em(cpu_dev, policy->cpus); if (is_bL_switching_enabled()) per_cpu(cpu_last_req_freq, policy->cpu) = diff --git a/drivers/opp/of.c b/drivers/opp/of.c index 5b75829a915d..4500ce46d476 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -1036,18 +1036,18 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_of_node); /* * Callback function provided to the Energy Model framework upon registration. - * This computes the power estimated by @CPU at @kHz if it is the frequency + * This computes the power estimated by @dev at @kHz if it is the frequency * of an existing OPP, or at the frequency of
[PATCH v3 1/5] ARM: dts: stm32: Add pin map for ltdc, spi5 on stm32f429-disco board
From: dillon min This patch adds the pin configuration for ltdc, spi5 controller on stm32f429-disco board. Signed-off-by: dillon min --- arch/arm/boot/dts/stm32f4-pinctrl.dtsi | 67 ++ 1 file changed, 67 insertions(+) diff --git a/arch/arm/boot/dts/stm32f4-pinctrl.dtsi b/arch/arm/boot/dts/stm32f4-pinctrl.dtsi index 392fa14..0eb107f 100644 --- a/arch/arm/boot/dts/stm32f4-pinctrl.dtsi +++ b/arch/arm/boot/dts/stm32f4-pinctrl.dtsi @@ -316,6 +316,73 @@ }; }; + ltdc_pins_f429_disco: ltdc-1 { + pins { + pinmux = , + /* LCD_HSYNC */ +, +/* LCD_VSYNC */ +, +/* LCD_CLK */ +, +/* LCD_R2 */ +, +/* LCD_R3 */ +, +/* LCD_R4 */ +, +/* LCD_R5 */ +, +/* LCD_R6*/ +, +/* LCD_R7 */ +, +/* LCD_G2 */ +, +/* LCD_G3 */ +, +/* LCD_G4 */ +, +/* LCD_B2 */ +, +/* LCD_B3*/ +, +/* LCD_G5 */ +, +/* LCD_G6 */ +, +/* LCD_G7 */ +, +/* LCD_B4 */ +, +/* LCD_B5 */ +, +/* LCD_B6 */ +, +/* LCD_B7 */ +; +/* LCD_DE */ + slew-rate = <2>; + }; + }; + + spi5_pins: spi5-0 { + pins1 { + pinmux = , + /* SPI5_CLK */ +; + /* SPI5_MOSI */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = ; + /* SPI5_MISO */ + bias-disable; + }; + }; + dcmi_pins: dcmi-0 { pins { pinmux = , /* DCMI_HSYNC */ -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 3/5] ARM: dts: stm32: enable ltdc binding with ili9341 on stm32429-disco board
From: dillon min Enable the ltdc & ili9341 on stm32429-disco board. Signed-off-by: dillon min --- Changes: V3: change dts binding compatible to "st,sf-tc240t-9370-t" V2: none v1: none arch/arm/boot/dts/stm32f429-disco.dts | 39 +++ 1 file changed, 39 insertions(+) diff --git a/arch/arm/boot/dts/stm32f429-disco.dts b/arch/arm/boot/dts/stm32f429-disco.dts index 30c0f67..4475e40 100644 --- a/arch/arm/boot/dts/stm32f429-disco.dts +++ b/arch/arm/boot/dts/stm32f429-disco.dts @@ -49,6 +49,8 @@ #include "stm32f429.dtsi" #include "stm32f429-pinctrl.dtsi" #include +#include +#include / { model = "STMicroelectronics STM32F429i-DISCO board"; @@ -127,3 +129,40 @@ pinctrl-names = "default"; status = "okay"; }; + + { + status = "okay"; + pinctrl-0 = <_pins_f429_disco>; + pinctrl-names = "default"; + + port { + ltdc_out_rgb: endpoint { + remote-endpoint = <_in_rgb>; + }; + }; +}; + + { + status = "okay"; + pinctrl-0 = <_pins>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + cs-gpios = < 2 GPIO_ACTIVE_LOW>; + dmas = < 3 2 0x400 0x0>, + < 4 2 0x400 0x0>; + dma-names = "rx", "tx"; + display: display@0{ + /* Connect panel-ilitek-9341 to stm32 via ltdc*/ + compatible = "st,sf-tc240t-9370-t"; + reg = <0>; + spi-3wire; + spi-max-frequency = <1000>; + dc-gpios = < 13 0>; + port { + panel_in_rgb: endpoint { + remote-endpoint = <_out_rgb>; + }; + }; + }; +}; -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v7 09/15] thermal: devfreq_cooling: change tracing function and arguments
Prepare for deleting the static and dynamic power calculation and clean the trace function. These two fields are going to be removed in the next changes. Reviewed-by: Steven Rostedt (VMware) # for tracing code Signed-off-by: Lukasz Luba --- drivers/thermal/devfreq_cooling.c | 3 +-- include/trace/events/thermal.h| 19 +-- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/thermal/devfreq_cooling.c b/drivers/thermal/devfreq_cooling.c index f7f32e98331b..52694d4bd819 100644 --- a/drivers/thermal/devfreq_cooling.c +++ b/drivers/thermal/devfreq_cooling.c @@ -286,8 +286,7 @@ static int devfreq_cooling_get_requested_power(struct thermal_cooling_device *cd *power = dyn_power + static_power; } - trace_thermal_power_devfreq_get_power(cdev, status, freq, dyn_power, - static_power, *power); + trace_thermal_power_devfreq_get_power(cdev, status, freq, *power); return 0; fail: diff --git a/include/trace/events/thermal.h b/include/trace/events/thermal.h index 135e5421f003..8a5f04888abd 100644 --- a/include/trace/events/thermal.h +++ b/include/trace/events/thermal.h @@ -153,31 +153,30 @@ TRACE_EVENT(thermal_power_cpu_limit, TRACE_EVENT(thermal_power_devfreq_get_power, TP_PROTO(struct thermal_cooling_device *cdev, struct devfreq_dev_status *status, unsigned long freq, - u32 dynamic_power, u32 static_power, u32 power), + u32 power), - TP_ARGS(cdev, status, freq, dynamic_power, static_power, power), + TP_ARGS(cdev, status, freq, power), TP_STRUCT__entry( __string(type, cdev->type) __field(unsigned long, freq ) - __field(u32, load ) - __field(u32, dynamic_power ) - __field(u32, static_power ) + __field(u32, busy_time) + __field(u32, total_time) __field(u32, power) ), TP_fast_assign( __assign_str(type, cdev->type); __entry->freq = freq; - __entry->load = (100 * status->busy_time) / status->total_time; - __entry->dynamic_power = dynamic_power; - __entry->static_power = static_power; + __entry->busy_time = status->busy_time; + __entry->total_time = status->total_time; __entry->power = power; ), - TP_printk("type=%s freq=%lu load=%u dynamic_power=%u static_power=%u power=%u", + TP_printk("type=%s freq=%lu load=%u power=%u", __get_str(type), __entry->freq, - __entry->load, __entry->dynamic_power, __entry->static_power, + __entry->total_time == 0 ? 0 : + (100 * __entry->busy_time) / __entry->total_time, __entry->power) ); -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Intel-gfx] [PATCH 3/3] misc/habalabs: don't set default fence_ops->wait
On Tue, May 12, 2020 at 4:14 AM Dave Airlie wrote: > > On Mon, 11 May 2020 at 19:37, Oded Gabbay wrote: > > > > On Mon, May 11, 2020 at 12:11 PM Daniel Vetter > > wrote: > > > > > > It's the default. > > Thanks for catching that. > > > > > > > > Also so much for "we're not going to tell the graphics people how to > > > review their code", dma_fence is a pretty core piece of gpu driver > > > infrastructure. And it's very much uapi relevant, including piles of > > > corresponding userspace protocols and libraries for how to pass these > > > around. > > > > > > Would be great if habanalabs would not use this (from a quick look > > > it's not needed at all), since open source the userspace and playing > > > by the usual rules isn't on the table. If that's not possible (because > > > it's actually using the uapi part of dma_fence to interact with gpu > > > drivers) then we have exactly what everyone promised we'd want to > > > avoid. > > > > We don't use the uapi parts, we currently only using the fencing and > > signaling ability of this module inside our kernel code. But maybe I > > didn't understand what you request. You want us *not* to use this > > well-written piece of kernel code because it is only used by graphics > > drivers ? > > I'm sorry but I don't get this argument, if this is indeed what you meant. > > We would rather drivers using a feature that has requirements on > correct userspace implementations of the feature have a userspace that > is open source and auditable. > > Fencing is tricky, cross-device fencing is really tricky, and having > the ability for a closed userspace component to mess up other people's > drivers, think i915 shared with closed habana userspace and shared > fences, decreases ability to debug things. > > Ideally we wouldn't offer users known untested/broken scenarios, so > yes we'd prefer that drivers that intend to expose a userspace fencing > api around dma-fence would adhere to the rules of the gpu drivers. > > I'm not say you have to drop using dma-fence, but if you move towards > cross-device stuff I believe other drivers would be correct in > refusing to interact with fences from here. The flip side is if you only used dma-fence.c "because it's there", and not because it comes with an uapi attached and a cross-driver kernel internal contract for how to interact with gpu drivers, then there's really not much point in using it. It's a custom-rolled wait_queue/event thing, that's all. Without the gpu uapi and gpu cross-driver contract it would be much cleaner to just use wait_queue directly, and that's a construct all kernel developers understand, not just gpu folks. From a quick look at least habanalabs doesn't use any of these uapi/cross-driver/gpu bits. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC] Remove AGP support from Radeon/Nouveau/TTM
Am 11.05.20 um 22:46 schrieb Alex Deucher: On Mon, May 11, 2020 at 4:41 PM John Paul Adrian Glaubitz wrote: On 5/11/20 10:05 PM, Alex Deucher wrote: For Nouveau I'm not 100% sure, but from the code it of hand looks like we can do it similar to Radeon. Please comment what you think about this. I would be against such a move as AGP graphics is still used by people running the powerpc and ppc64 Debian ports on their vintage hardware [1]. I have also CC'ed the debian-powerpc mailing list so that other users can voice their opinion. Note there is no loss of functionality here, at least on radeon hardware. It just comes down to which MMU gets used for access to system memory, the AGP MMU on the chipset or the MMU built into the GPU. On powerpc hardware, AGP has been particularly unstable, and IIRC, AGP has been disabled by default on radeon on powerpc for a while. Do you have a code reference at hand for this bit of information (AGP being disabled on Macs)? It was disabled 2 years ago: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=037d1a66ae640ca2723f47c0115ffa9e603699b3 To be honest from the hacks we have in there to get this working I'm even surprised that this ever worked at all on PowerPC. Going to extend this patch for now and add a config option to not compile in AGP GART support for TTM any more instead of removing it. Christian. Alex Thanks, Adrian -- .''`. John Paul Adrian Glaubitz : :' : Debian Developer - glaub...@debian.org `. `' Freie Universitaet Berlin - glaub...@physik.fu-berlin.de `-GPG: 62FF 8A75 84E0 2956 9546 0006 7426 3B37 F5B5 F913 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 1/3] drm/radeon: remove AGP support
On 2020-05-11 10:12 p.m., Alex Deucher wrote: > On Mon, May 11, 2020 at 1:17 PM Christian König > wrote: >> >> AGP is deprecated for 10+ years now and not used any more on modern hardware. >> >> Old hardware should continue to work in PCI mode. > > Might want to clarify that there is no loss of functionality here. > Something like: > > "There is no loss of functionality here. GPUs will continue to > function. This just drops the use of the AGP MMU in the chipset in > favor of the MMU on the device which has proven to be much more > reliable. Due to its unreliability, AGP support has been disabled on > PowerPC for years already so there is no change on PowerPC." There's a difference between something being disabled by default or not being available at all. We may decide it's worth it anyway, but let's do it based on facts. -- Earthling Michel Dänzer | https://redhat.com Libre software enthusiast | Mesa and X developer ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] dma-buf: fix use-after-free in dmabuffs_dname
On Tue, May 12, 2020 at 10:43:18AM +0530, Charan Teja Kalla wrote: > > Ok, but watch out, now you have 2 different reference counts for the > > same structure. Keeping them coordinated is almost always an impossible > > task so you need to only rely on one. If you can't use the file api, > > just drop all of the reference counting logic in there and only use the > > kref one. > > I feel that changing the refcount logic now to dma-buf objects involve > changes in > > the core dma-buf framework. NO? Instead, how about passing the user passed > name directly > > in the ->d_fsdata inplace of dmabuf object? Because we just need user passed > name in the > > dmabuffs_dname(). With this we can avoid the need for extra refcount on > dmabuf. Odd formatting :( > Posted patch-V2: https://lkml.org/lkml/2020/5/8/158 Please just post links to lore.kernel.org, we have no control over lkml.org at all. I'll go review that patch now... greg k-h ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC v2] drm/connector: Add support for privacy-screen properties (v2)
Hi, On 5/12/20 9:49 AM, Pekka Paalanen wrote: On Mon, 11 May 2020 19:47:24 +0200 Hans de Goede wrote: From: Rajat Jain Add support for generic electronic privacy screen properties, that can be added by systems that have an integrated EPS. Changes in v2 (Hans de Goede) - Create 2 properties, "privacy-screen sw-state" and "privacy-screen hw-state", to deal with devices where the OS might be locked out of making state changes - Write kerneldoc explaining how the 2 properties work together, what happens when changes to the state are made outside of the DRM code's control, etc. Signed-off-by: Rajat Jain Co-authored-by: Hans de Goede Signed-off-by: Hans de Goede --- Documentation/gpu/drm-kms.rst | 2 + drivers/gpu/drm/drm_atomic_uapi.c | 6 ++ drivers/gpu/drm/drm_connector.c | 100 ++ include/drm/drm_connector.h | 50 +++ 4 files changed, 158 insertions(+) ... diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 644f0ad10671..01360edc2376 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1186,6 +1186,45 @@ static const struct drm_prop_enum_list dp_colorspaces[] = { *can also expose this property to external outputs, in which case they *must support "None", which should be the default (since external screens *have a built-in scaler). + * + * privacy-screen sw-state, privacy-screen hw-state: + * These 2 optional properties can be used to query the state of the + * electronic privacy screen that is available on some displays; and in + * some cases also control the state. If a driver implements these + * properties then both properties must be present. + * + * "privacy-screen hw-state" is read-only and reflects the actual state + * of the privacy-screen, possible values: "Enabled", "Disabled, + * "Enabled, locked", "Disabled, locked". The locked states indicate + * that the state cannot be changed through the DRM API. E.g. there + * might be devices where the firmware-setup options, or a hardware + * slider-switch, offer always on / off modes. + * + * "privacy-screen sw-state" can be set to change the privacy-screen state + * when not locked. In this case the driver must update the hw-state + * property to reflect the new state on completion of the commit of the + * sw-state property. Setting the sw-state property when the hw-state is + * locked must be interpreted by the driver as a request to change the + * state to the set state when the hw-state becomes unlocked. E.g. if + * "privacy-screen hw-state" is "Enabled, locked" and the sw-state + * gets set to "Disabled" followed by the user unlocking the state by + * changing the slider-switch position, then the driver must set the + * state to "Disabled" upon receiving the unlock event. + * + * In some cases the privacy-screen state might change outside of control + * of the DRM code. E.g. there might be a firmware handled hotkey which + * toggles the state, or the state might be changed through another Hi, in the above three lines, I'd use the term "hardware state" instead of just "state" to be explicit. Or should it be "physical state" since "hardware state" might be confused with "hw-state" property state? Maybe "actual state"? That is what is used a few lines higher: '"privacy-screen hw-state" is read-only and reflects the actual state' And you use it yourself to describe what we want below: I don't mind as long as it's unambiguous and distinguishes explicitly between actual and the two property states. So since you and I both naturally described it as "actual state" without thinking too much what we where writing at the time (I guess that applies to your use too), "actual state" seems a good fit ? + * userspace API such as writing /proc/acpi/ibm/lcdshadow. In this case + * the driver must update both the hw-state and the sw-state to reflect + * the new value, overwriting any pending state requests in the sw-state. + * + * Note that the ability for the state to change outside of control of + * the DRM master process means that userspace must not cache the value + * of the sw-state. Ccaching the sw-state value and including it in later Extra 'c' in "Caching". Ack, will fix. + * atomic commits may lead to overriding a state change done through e.g. + * a firmware handled hotkey. Therefor userspace must not include the + * privacy-screen sw-state in an atomic commit unless it wants to change + * its value. */ This documentation and intended behaviour looks perfect to me. Great I'm glad you like it. If you can record an R-b just for the doc, please have: Reviewed-by: Pekka Paalanen You can also downgrade that to Acked-by for the whole patch from my behalf. I don't know of a way to add partial Reviewed-by tags, so unless
[PATCH v7 03/15] PM / EM: update callback structure and add device pointer
The Energy Model framework is going to support devices other that CPUs. In order to make this happen change the callback function and add pointer to a device as an argument. Update the related users to use new function and new callback from the Energy Model. Signed-off-by: Lukasz Luba --- drivers/cpufreq/scmi-cpufreq.c | 11 +++ drivers/opp/of.c | 9 ++--- include/linux/energy_model.h | 15 --- kernel/power/energy_model.c| 9 + 4 files changed, 18 insertions(+), 26 deletions(-) diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c index 61623e2ff149..11ee24e06d12 100644 --- a/drivers/cpufreq/scmi-cpufreq.c +++ b/drivers/cpufreq/scmi-cpufreq.c @@ -103,17 +103,12 @@ scmi_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask) } static int __maybe_unused -scmi_get_cpu_power(unsigned long *power, unsigned long *KHz, int cpu) +scmi_get_cpu_power(unsigned long *power, unsigned long *KHz, + struct device *cpu_dev) { - struct device *cpu_dev = get_cpu_device(cpu); unsigned long Hz; int ret, domain; - if (!cpu_dev) { - pr_err("failed to get cpu%d device\n", cpu); - return -ENODEV; - } - domain = handle->perf_ops->device_domain_id(cpu_dev); if (domain < 0) return domain; @@ -200,7 +195,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy) policy->fast_switch_possible = true; - em_register_perf_domain(policy->cpus, nr_opp, _cb); + em_dev_register_perf_domain(cpu_dev, nr_opp, _cb, policy->cpus); return 0; diff --git a/drivers/opp/of.c b/drivers/opp/of.c index 9cd8f0adacae..5b75829a915d 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -1047,9 +1047,8 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_of_node); * calculation failed because of missing parameters, 0 otherwise. */ static int __maybe_unused _get_cpu_power(unsigned long *mW, unsigned long *kHz, -int cpu) +struct device *cpu_dev) { - struct device *cpu_dev; struct dev_pm_opp *opp; struct device_node *np; unsigned long mV, Hz; @@ -1057,10 +1056,6 @@ static int __maybe_unused _get_cpu_power(unsigned long *mW, unsigned long *kHz, u64 tmp; int ret; - cpu_dev = get_cpu_device(cpu); - if (!cpu_dev) - return -ENODEV; - np = of_node_get(cpu_dev->of_node); if (!np) return -EINVAL; @@ -1128,6 +1123,6 @@ void dev_pm_opp_of_register_em(struct cpumask *cpus) if (ret || !cap) return; - em_register_perf_domain(cpus, nr_opp, _cb); + em_dev_register_perf_domain(cpu_dev, nr_opp, _cb, cpus); } EXPORT_SYMBOL_GPL(dev_pm_opp_of_register_em); diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h index 7c048df98447..7076cb22b247 100644 --- a/include/linux/energy_model.h +++ b/include/linux/energy_model.h @@ -48,24 +48,25 @@ struct em_perf_domain { struct em_data_callback { /** * active_power() - Provide power at the next performance state of -* a CPU +* a device * @power : Active power at the performance state in mW * (modified) * @freq: Frequency at the performance state in kHz * (modified) -* @cpu : CPU for which we do this operation +* @dev : Device for which we do this operation (can be a CPU) * -* active_power() must find the lowest performance state of 'cpu' above +* active_power() must find the lowest performance state of 'dev' above * 'freq' and update 'power' and 'freq' to the matching active power * and frequency. * -* The power is the one of a single CPU in the domain, expressed in -* milli-watts. It is expected to fit in the [0, EM_MAX_POWER] -* range. +* In case of CPUs, the power is the one of a single CPU in the domain, +* expressed in milli-watts. It is expected to fit in the +* [0, EM_MAX_POWER] range. * * Return 0 on success. */ - int (*active_power)(unsigned long *power, unsigned long *freq, int cpu); + int (*active_power)(unsigned long *power, unsigned long *freq, + struct device *dev); }; #define EM_DATA_CB(_active_power_cb) { .active_power = &_active_power_cb } diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c index 875b163e54ab..5b8a1566526a 100644 --- a/kernel/power/energy_model.c +++ b/kernel/power/energy_model.c @@ -78,8 +78,9 @@ core_initcall(em_debug_init); #else /* CONFIG_DEBUG_FS */ static void em_debug_create_pd(struct em_perf_domain *pd, int cpu) {} #endif -static struct em_perf_domain
[PATCH v7 00/15] Add support for devices in the Energy Model
Hi all, This patch set introduces support for devices in the Energy Model (EM) framework. It will unify the power model for thermal subsystem. It will make simpler to add support for new devices willing to use more advanced features (like Intelligent Power Allocation). Now it should require less knowledge and effort for driver developer to add e.g. GPU driver with simple energy model. A more sophisticated energy model in the thermal framework is also possible, driver needs to provide a dedicated callback function. More information can be found in the updated documentation file. First 7 patches are refactoring Energy Model framework to add support of other devices that CPUs. They change: - naming convention from 'capacity' to 'performance' state, - API arguments adding device pointer and not rely only on cpumask, - change naming when 'cpu' was used, now it's a 'device' - internal structure to maintain registered devices - update users to the new API Patch 8 updates OPP framework helper function to be more generic, not CPU specific. Patches 9-14 change devfreq cooling, dropping part of old power model and adding registration with Energy Model via exported GPL function. The last path is a simple change for Panfrost GPU driver. The patch set is based on linux-next tag next-20200508. Changes: v7: - all the EM changes are for patch 4/10 from v6 -- added em_perf_domain structure into struct device in order to simplify code (suggested by Daniel) -- removed kref, em_pd, debug_dir from em_device (suggested by Daniel) -- refactored code and removed unsed functions -- refactored checking if EM exists for a CPU and deleted em_cpus_pd_exist() -- simplified em_pd_get() and em_cpu_get() -- removed em_debug_type_show() -- removed a few unused debug prints -- changed debug dir name in order to remove em_debug_type_show() and em_debug_dev_show() functions -- removed em_dev_list and em_device since it is now possible to use struct device and rely on it - thermal: split patch 9/10 from v6 as requested by Daniel and created 6 new: -- patch v7 9/15 with only tracing change - exactly the same code so I keep 'Reviewed-by # for tracing code' from Steven Rostedt -- patch 10/15 and 11/14 takes more consistent state of devfreq device -- patch 12/15 which adds Energy Model register/unregister functions -- patch 13/15 which uses the new Energy Model -- patch 14/15 adjusts headers license into the SPDX v6 [6]: - split patch 1/5 from v5 into smaller patches as requested by Daniel and dropped ACK from Quentin which was in the old there - added function em_dev_register_perf_domain as suggested by Daniel, which would help transition into the new API - changed 'cs' (capacity state) in different places into 'ps' (performance state), since now there are many smaller patches (previously skipped because of too big size of the patch with main features and left to do later) - changed cpumask_equal() to cpumask_intersects() when checking if 'cpus' coming as an argument to registration function might overlap with already known; this shouldn't be an issue when cpufreq policy is OK, but a check doesn't harm - added Reviewed-by from Alyssa into Panfrost related patch - dropped Matthias patch with PM QoS from the series since it's in the next now v5 [5]: - devfreq cooling: rebased on top of pending patch introducing PM QoS limits - devfreq cooling: added Matthias's patch to make this series build check pass - devfreq cooling: removed OPP disable code and switched to PM QoS - devfreq cooling: since thermal code always used a pointer to devfreq_dev_status, switched to work on a local copy and avoid potential race when either busy_time or total_time could change in the background - devfreq cooling: added _normalize_load() and handle all scenarios when busy_time and total_time could have odd values (even raw counters) - Energy Model patch 2/4: removed prints from cpufreq drivers and added print inside dev_pm_opp_of_register_em() - update patch 2/4 description to better reflect upcoming changes - collected ACK from Quentin for patch 1/4 and Reviewed-by from Steven for 4/4 v4 [4]: - devfreq cooling: added two new registration functions, which will take care of registering EM for the device and simplify drivers code (suggested by Robin and Rob) - Energy Model: changed unregistering code, added kref to track usage, added code freeing tables, added helper function - added return value to function dev_pm_opp_of_register_em() and updated CPUFreq drivers code, added debug prints in case of failure - updated comments in devfreq cooling removing statement that only simple_ondemand devfreq governor is supported to work with power extentions - fixed spelling in the documentation (reported by Randy) v3 [3]: - added back the cpumask 'cpus' in the em_perf_domain due potential cache misses - removed _is_cpu_em() since there is no need for it - changed function name from em_pd_energy() to em_cpu_energy(), which is optimized
[PATCH v7 04/15] PM / EM: add support for other devices than CPUs in Energy Model
Add support for other devices that CPUs. The registration function does not require a valid cpumask pointer and is ready to handle new devices. Some of the internal structures has been reorganized in order to keep consistent view (like removing per_cpu pd pointers). To track usage of the Energy Model structures, they are protected with kref. Signed-off-by: Lukasz Luba --- include/linux/device.h | 5 + include/linux/energy_model.h | 28 +++-- kernel/power/energy_model.c | 237 --- 3 files changed, 187 insertions(+), 83 deletions(-) diff --git a/include/linux/device.h b/include/linux/device.h index ac8e37cd716a..7023d3ea189b 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -13,6 +13,7 @@ #define _DEVICE_H_ #include +#include #include #include #include @@ -559,6 +560,10 @@ struct device { struct dev_pm_info power; struct dev_pm_domain*pm_domain; +#ifdef CONFIG_ENERGY_MODEL + struct em_perf_domain *em_pd; +#endif + #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN struct irq_domain *msi_domain; #endif diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h index 7076cb22b247..f5a88486d1c4 100644 --- a/include/linux/energy_model.h +++ b/include/linux/energy_model.h @@ -12,8 +12,10 @@ /** * em_perf_state - Performance state of a performance domain - * @frequency: The CPU frequency in KHz, for consistency with CPUFreq - * @power: The power consumed by 1 CPU at this level, in milli-watts + * @frequency: The frequency in KHz, for consistency with CPUFreq + * @power: The power consumed at this level, in milli-watts (by 1 CPU or + by a registered device). It can be a total power: static and + dynamic. * @cost: The cost coefficient associated with this level, used during * energy calculation. Equal to: power * max_frequency / frequency */ @@ -27,12 +29,15 @@ struct em_perf_state { * em_perf_domain - Performance domain * @table: List of performance states, in ascending order * @nr_perf_states:Number of performance states - * @cpus: Cpumask covering the CPUs of the domain + * @cpus: Cpumask covering the CPUs of the domain. It's here + * for performance reasons to avoid potential cache + * misses during energy calculations in the scheduler * - * A "performance domain" represents a group of CPUs whose performance is - * scaled together. All CPUs of a performance domain must have the same - * micro-architecture. Performance domains often have a 1-to-1 mapping with - * CPUFreq policies. + * In case of CPU device, a "performance domain" represents a group of CPUs + * whose performance is scaled together. All CPUs of a performance domain + * must have the same micro-architecture. Performance domains often have + * a 1-to-1 mapping with CPUFreq policies. In case of other devices the 'cpus' + * field is unused. */ struct em_perf_domain { struct em_perf_state *table; @@ -71,10 +76,12 @@ struct em_data_callback { #define EM_DATA_CB(_active_power_cb) { .active_power = &_active_power_cb } struct em_perf_domain *em_cpu_get(int cpu); +struct em_perf_domain *em_pd_get(struct device *dev); int em_register_perf_domain(cpumask_t *span, unsigned int nr_states, struct em_data_callback *cb); int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, struct em_data_callback *cb, cpumask_t *span); +void em_dev_unregister_perf_domain(struct device *dev); /** * em_pd_energy() - Estimates the energy consumed by the CPUs of a perf. domain @@ -184,10 +191,17 @@ int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, { return -EINVAL; } +static inline void em_dev_unregister_perf_domain(struct device *dev) +{ +} static inline struct em_perf_domain *em_cpu_get(int cpu) { return NULL; } +static inline struct em_perf_domain *em_pd_get(struct device *dev) +{ + return NULL; +} static inline unsigned long em_pd_energy(struct em_perf_domain *pd, unsigned long max_util, unsigned long sum_util) { diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c index 5b8a1566526a..9cc7f2973600 100644 --- a/kernel/power/energy_model.c +++ b/kernel/power/energy_model.c @@ -2,8 +2,9 @@ /* * Energy Model of CPUs * - * Copyright (c) 2018, Arm ltd. + * Copyright (c) 2018-2020, Arm ltd. * Written by: Quentin Perret, Arm ltd. + * Improvements provided by: Lukasz Luba, Arm ltd. */ #define pr_fmt(fmt) "energy_model: " fmt @@ -15,15 +16,17 @@ #include #include -/* Mapping of each CPU to the performance domain to which it belongs. */ -static DEFINE_PER_CPU(struct em_perf_domain *, em_data); - /* * Mutex serializing the registrations of performance domains and letting *
[PATCH v7 05/15] PM / EM: remove em_register_perf_domain
Remove old function em_register_perf_domain which is no longer needed. There is em_dev_register_perf_domain that covers old use cases and new as well. Acked-by: Daniel Lezcano Signed-off-by: Lukasz Luba --- include/linux/energy_model.h | 7 --- kernel/power/energy_model.c | 25 - 2 files changed, 32 deletions(-) diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h index f5a88486d1c4..6b56ae6c6a89 100644 --- a/include/linux/energy_model.h +++ b/include/linux/energy_model.h @@ -77,8 +77,6 @@ struct em_data_callback { struct em_perf_domain *em_cpu_get(int cpu); struct em_perf_domain *em_pd_get(struct device *dev); -int em_register_perf_domain(cpumask_t *span, unsigned int nr_states, - struct em_data_callback *cb); int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, struct em_data_callback *cb, cpumask_t *span); void em_dev_unregister_perf_domain(struct device *dev); @@ -180,11 +178,6 @@ static inline int em_pd_nr_perf_states(struct em_perf_domain *pd) struct em_data_callback {}; #define EM_DATA_CB(_active_power_cb) { } -static inline int em_register_perf_domain(cpumask_t *span, - unsigned int nr_states, struct em_data_callback *cb) -{ - return -EINVAL; -} static inline int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, struct em_data_callback *cb, cpumask_t *span) diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c index 9cc7f2973600..3c5c579ad2c2 100644 --- a/kernel/power/energy_model.c +++ b/kernel/power/energy_model.c @@ -322,31 +322,6 @@ int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, } EXPORT_SYMBOL_GPL(em_dev_register_perf_domain); -/** - * em_register_perf_domain() - Register the Energy Model of a performance domain - * @span : Mask of CPUs in the performance domain - * @nr_states : Number of capacity states to register - * @cb : Callback functions providing the data of the Energy Model - * - * Create Energy Model tables for a performance domain using the callbacks - * defined in cb. - * - * If multiple clients register the same performance domain, all but the first - * registration will be ignored. - * - * Return 0 on success - */ -int em_register_perf_domain(cpumask_t *span, unsigned int nr_states, - struct em_data_callback *cb) -{ - struct device *cpu_dev; - - cpu_dev = get_cpu_device(cpumask_first(span)); - - return em_dev_register_perf_domain(cpu_dev, nr_states, cb, span); -} -EXPORT_SYMBOL_GPL(em_register_perf_domain); - /** * em_dev_unregister_perf_domain() - Unregister Energy Model (EM) for a device * @dev: Device for which the EM is registered -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v7 10/15] thermal: devfreq_cooling: get device load and frequency directly
Devfreq cooling needs to now the correct status of the device in order to operate. Do not rely on Devfreq last_status which might be a stale data and get more up-to-date values of load and frequency. In addition this patch adds normalization function, which also makes sure that whatever data comes from the device, it is in a sane range. Signed-off-by: Lukasz Luba --- drivers/thermal/devfreq_cooling.c | 38 +++ 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/drivers/thermal/devfreq_cooling.c b/drivers/thermal/devfreq_cooling.c index 52694d4bd819..396f16bb6566 100644 --- a/drivers/thermal/devfreq_cooling.c +++ b/drivers/thermal/devfreq_cooling.c @@ -235,6 +235,24 @@ static inline unsigned long get_total_power(struct devfreq_cooling_device *dfc, voltage); } +static void _normalize_load(struct devfreq_dev_status *status) +{ + /* Make some space if needed */ + if (status->busy_time > 0x) { + status->busy_time >>= 10; + status->total_time >>= 10; + } + + if (status->busy_time > status->total_time) + status->busy_time = status->total_time; + + status->busy_time *= 100; + status->busy_time /= status->total_time ? : 1; + + /* Avoid division by 0 */ + status->busy_time = status->busy_time ? : 1; + status->total_time = 100; +} static int devfreq_cooling_get_requested_power(struct thermal_cooling_device *cdev, struct thermal_zone_device *tz, @@ -242,14 +260,22 @@ static int devfreq_cooling_get_requested_power(struct thermal_cooling_device *cd { struct devfreq_cooling_device *dfc = cdev->devdata; struct devfreq *df = dfc->devfreq; - struct devfreq_dev_status *status = >last_status; + struct devfreq_dev_status status; unsigned long state; - unsigned long freq = status->current_frequency; + unsigned long freq; unsigned long voltage; u32 dyn_power = 0; u32 static_power = 0; int res; + mutex_lock(>lock); + res = df->profile->get_dev_status(df->dev.parent, ); + mutex_unlock(>lock); + if (res) + return res; + + freq = status.current_frequency; + state = freq_get_state(dfc, freq); if (state == THERMAL_CSTATE_INVALID) { res = -EAGAIN; @@ -277,16 +303,18 @@ static int devfreq_cooling_get_requested_power(struct thermal_cooling_device *cd } else { dyn_power = dfc->power_table[state]; + _normalize_load(); + /* Scale dynamic power for utilization */ - dyn_power *= status->busy_time; - dyn_power /= status->total_time; + dyn_power *= status.busy_time; + dyn_power /= status.total_time; /* Get static power */ static_power = get_static_power(dfc, freq); *power = dyn_power + static_power; } - trace_thermal_power_devfreq_get_power(cdev, status, freq, *power); + trace_thermal_power_devfreq_get_power(cdev, , freq, *power); return 0; fail: -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 1/2] mtd: rawnand: brcmnand: fix hamming oob layout
First 2 bytes are used in large-page nand. Fixes: ef5eeea6e911 ("mtd: nand: brcm: switch to mtd_ooblayout_ops") Cc: sta...@vger.kernel.org Signed-off-by: Álvaro Fernández Rojas --- v3: invert patch order v2: extend original comment drivers/mtd/nand/raw/brcmnand/brcmnand.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c index e4e3ceeac38f..1c1070111ebc 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c @@ -1116,11 +1116,14 @@ static int brcmnand_hamming_ooblayout_free(struct mtd_info *mtd, int section, if (!section) { /* * Small-page NAND use byte 6 for BBI while large-page -* NAND use byte 0. +* NAND use bytes 0 and 1. */ - if (cfg->page_size > 512) - oobregion->offset++; - oobregion->length--; + if (cfg->page_size > 512) { + oobregion->offset += 2; + oobregion->length -= 2; + } else { + oobregion->length--; + } } } -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v7 11/15] thermal: devfreq_cooling: work on a copy of device status
Devfreq framework can change the device status in the background. To mitigate this situation make a copy of the status structure and use it for internal calculations. Signed-off-by: Lukasz Luba --- drivers/thermal/devfreq_cooling.c | 14 ++ 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/thermal/devfreq_cooling.c b/drivers/thermal/devfreq_cooling.c index 396f16bb6566..36ec6a48606c 100644 --- a/drivers/thermal/devfreq_cooling.c +++ b/drivers/thermal/devfreq_cooling.c @@ -348,14 +348,20 @@ static int devfreq_cooling_power2state(struct thermal_cooling_device *cdev, { struct devfreq_cooling_device *dfc = cdev->devdata; struct devfreq *df = dfc->devfreq; - struct devfreq_dev_status *status = >last_status; - unsigned long freq = status->current_frequency; + struct devfreq_dev_status status; unsigned long busy_time; + unsigned long freq; s32 dyn_power; u32 static_power; s32 est_power; int i; + mutex_lock(>lock); + status = df->last_status; + mutex_unlock(>lock); + + freq = status.current_frequency; + if (dfc->power_ops->get_real_power) { /* Scale for resource utilization */ est_power = power * dfc->res_util; @@ -367,8 +373,8 @@ static int devfreq_cooling_power2state(struct thermal_cooling_device *cdev, dyn_power = dyn_power > 0 ? dyn_power : 0; /* Scale dynamic power for utilization */ - busy_time = status->busy_time ?: 1; - est_power = (dyn_power * status->total_time) / busy_time; + busy_time = status.busy_time ?: 1; + est_power = (dyn_power * status.total_time) / busy_time; } /* -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 0/5] Enable ilitek ili9341 on stm32f429-disco board
From: dillon min This patchset has following changes: V3: merge original tiny/ili9341.c driver to panel/panel-ilitek-ili9341.c to support serial spi & parallel rgb interface in one driver. update ilitek,ili9341.yaml dts binding documentation. update stm32f429-disco dts binding V2: verify ilitek,ili9341.yaml with make O=../linux-stm32 dt_binding_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/display/panel/ ilitek,ili9341.yaml V1: add ili9341 drm panel driver add ltdc, spi5 controller for stm32f429-disco add ltdc, spi5 pin map for stm32f429-disco add docs about ili9341 fix ltdc driver loading hang in clk set rate bug dillon min (5): ARM: dts: stm32: Add pin map for ltdc, spi5 on stm32f429-disco board dt-bindings: display: panel: Add ilitek ili9341 panel bindings ARM: dts: stm32: enable ltdc binding with ili9341 on stm32429-disco board clk: stm32: Fix stm32f429 ltdc driver loading hang in clk set rate. keep ltdc clk running after kernel startup drm/panel: Add ilitek ili9341 driver .../bindings/display/panel/ilitek,ili9341.yaml | 68 ++ arch/arm/boot/dts/stm32f4-pinctrl.dtsi | 67 ++ arch/arm/boot/dts/stm32f429-disco.dts | 39 ++ drivers/clk/clk-stm32f4.c | 5 +- drivers/gpu/drm/panel/Kconfig | 12 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 700 + 7 files changed, 890 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml create mode 100644 drivers/gpu/drm/panel/panel-ilitek-ili9341.c -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v7 12/15] thermal: devfreq_cooling: add new registration functions with Energy Model
The Energy Model (EM) framework supports devices such as Devfreq. Create new registration functions which automatically register EM for the thermal devfreq_cooling devices. This patch prepares the code for coming changes which are going to replace old power model with the new EM. Signed-off-by: Lukasz Luba --- drivers/thermal/devfreq_cooling.c | 99 ++- include/linux/devfreq_cooling.h | 22 +++ 2 files changed, 120 insertions(+), 1 deletion(-) diff --git a/drivers/thermal/devfreq_cooling.c b/drivers/thermal/devfreq_cooling.c index 36ec6a48606c..c7ffed2d6ee0 100644 --- a/drivers/thermal/devfreq_cooling.c +++ b/drivers/thermal/devfreq_cooling.c @@ -58,6 +58,8 @@ static DEFINE_IDA(devfreq_ida); * @capped_state: index to cooling state with in dynamic power budget * @req_max_freq: PM QoS request for limiting the maximum frequency * of the devfreq device. + * @em:Energy Model which represents the associated Devfreq device + * @em_registered: Devfreq cooling registered the EM and should free it. */ struct devfreq_cooling_device { int id; @@ -71,6 +73,8 @@ struct devfreq_cooling_device { u32 res_util; int capped_state; struct dev_pm_qos_request req_max_freq; + struct em_perf_domain *em; + bool em_registered; }; static int devfreq_cooling_get_max_state(struct thermal_cooling_device *cdev, @@ -594,22 +598,115 @@ struct thermal_cooling_device *devfreq_cooling_register(struct devfreq *df) } EXPORT_SYMBOL_GPL(devfreq_cooling_register); +/** + * devfreq_cooling_em_register_power() - Register devfreq cooling device with + * power information and attempt to register Energy Model (EM) + * @df:Pointer to devfreq device. + * @dfc_power: Pointer to devfreq_cooling_power. + * @em_cb: Callback functions providing the data of the EM + * + * Register a devfreq cooling device and attempt to register Energy Model. The + * available OPPs must be registered for the device. + * + * If @dfc_power is provided, the cooling device is registered with the + * power extensions. If @em_cb is provided it will be called for each OPP to + * calculate power value and cost. If @em_cb is not provided then simple Energy + * Model is going to be used, which requires "dynamic-power-coefficient" a + * devicetree property. + */ +struct thermal_cooling_device * +devfreq_cooling_em_register_power(struct devfreq *df, + struct devfreq_cooling_power *dfc_power, + struct em_data_callback *em_cb) +{ + struct thermal_cooling_device *cdev; + struct devfreq_cooling_device *dfc; + struct device_node *np = NULL; + struct device *dev; + int nr_opp, ret; + + if (IS_ERR_OR_NULL(df)) + return ERR_PTR(-EINVAL); + + dev = df->dev.parent; + + if (em_cb) { + nr_opp = dev_pm_opp_get_opp_count(dev); + if (nr_opp <= 0) { + dev_err(dev, "No valid OPPs found\n"); + return ERR_PTR(-EINVAL); + } + + ret = em_dev_register_perf_domain(dev, nr_opp, em_cb, NULL); + } else { + ret = dev_pm_opp_of_register_em(dev, NULL); + } + + if (ret) + dev_warn(dev, "Unable to register EM for devfreq cooling device (%d)\n", +ret); + + if (dev->of_node) + np = of_node_get(dev->of_node); + + cdev = of_devfreq_cooling_register_power(np, df, dfc_power); + + if (np) + of_node_put(np); + + if (IS_ERR_OR_NULL(cdev)) { + if (!ret) + em_dev_unregister_perf_domain(dev); + } else { + dfc = cdev->devdata; + dfc->em_registered = !ret; + } + + return cdev; +} +EXPORT_SYMBOL_GPL(devfreq_cooling_em_register_power); + +/** + * devfreq_cooling_em_register() - Register devfreq cooling device together + * with Energy Model. + * @df:Pointer to devfreq device. + * @em_cb: Callback functions providing the data of the Energy Model + * + * This function attempts to register Energy Model for devfreq device and then + * register the devfreq cooling device. + */ +struct thermal_cooling_device * +devfreq_cooling_em_register(struct devfreq *df, struct em_data_callback *em_cb) +{ + return devfreq_cooling_em_register_power(df, NULL, em_cb); +} +EXPORT_SYMBOL_GPL(devfreq_cooling_em_register); + /** * devfreq_cooling_unregister() - Unregister devfreq cooling device. * @cdev: Pointer to devfreq cooling device to unregister. + * + * Unregisters devfreq cooling device and related Energy Model if it was + * present. */ void devfreq_cooling_unregister(struct thermal_cooling_device *cdev) { struct devfreq_cooling_device *dfc; + struct device *dev; -
Re: [PATCH v5 1/6] drm/bridge: ti-sn65dsi86: Export bridge GPIOs to Linux
On Thu 07 May 14:34 PDT 2020, Douglas Anderson wrote: > The ti-sn65dsi86 MIPI DSI to eDP bridge chip has 4 pins on it that can > be used as GPIOs in a system. Each pin can be configured as input, > output, or a special function for the bridge chip. These are: > - GPIO1: SUSPEND Input > - GPIO2: DSIA VSYNC > - GPIO3: DSIA HSYNC or VSYNC > - GPIO4: PWM > > Let's expose these pins as GPIOs. A few notes: > - Access to ti-sn65dsi86 is via i2c so we set "can_sleep". > - These pins can't be configured for IRQ. > - There are no programmable pulls or other fancy features. > - Keeping the bridge chip powered might be expensive. The driver is > setup such that if all used GPIOs are only inputs we'll power the > bridge chip on just long enough to read the GPIO and then power it > off again. Setting a GPIO as output will keep the bridge powered. > - If someone releases a GPIO we'll implicitly switch it to an input so > we no longer need to keep the bridge powered for it. > > Because of all of the above limitations we just need to implement a > bare-bones GPIO driver. The device tree bindings already account for > this device being a GPIO controller so we only need the driver changes > for it. > > NOTE: Despite the fact that these pins are nominally muxable I don't > believe it makes sense to expose them through the pinctrl interface as > well as the GPIO interface. The special functions are things that the > bridge chip driver itself would care about and it can just configure > the pins as needed. > I'm working on a patch for supporting the PWM controller in the bridge and as you say the muxing for that is better left internal to the bridge driver. > Signed-off-by: Douglas Anderson > Cc: Linus Walleij > Cc: Bartosz Golaszewski Reviewed-by: Bjorn Andersson Regards, Bjorn > --- > Removed Stephen's review tag in v5 to confirm he's good with the way I > implemented of_xlate. > > Changes in v5: > - Use of_xlate so that numbers in dts start at 1, not 0. > > Changes in v4: > - Don't include gpio.h > - Use gpiochip_get_data() instead of container_of() to get data. > - GPIOF_DIR_XXX => GPIO_LINE_DIRECTION_XXX > - Use Linus W's favorite syntax to read a bit from a bitfield. > - Define and use SN_GPIO_MUX_MASK. > - Add a comment about why we use a bitmap for gchip_output. > > Changes in v3: > - Becaue => Because > - Add a kernel-doc to our pdata to clarify double-duty of gchip_output. > - More comments about how powering off affects us (get_dir, dir_input). > - Cleanup tail of ti_sn_setup_gpio_controller() to avoid one "return". > - Use a bitmap rather than rolling my own. > > Changes in v2: > - ("Export...GPIOs") is 1/2 of replacement for ("Allow...bridge GPIOs") > > drivers/gpu/drm/bridge/ti-sn65dsi86.c | 214 ++ > 1 file changed, 214 insertions(+) > > diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c > b/drivers/gpu/drm/bridge/ti-sn65dsi86.c > index 6ad688b320ae..4e8df948b3b8 100644 > --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c > +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c > @@ -4,9 +4,11 @@ > * datasheet: http://www.ti.com/lit/ds/symlink/sn65dsi86.pdf > */ > > +#include > #include > #include > #include > +#include > #include > #include > #include > @@ -54,6 +56,14 @@ > #define BPP_18_RGB BIT(0) > #define SN_HPD_DISABLE_REG 0x5C > #define HPD_DISABLE BIT(0) > +#define SN_GPIO_IO_REG 0x5E > +#define SN_GPIO_INPUT_SHIFT 4 > +#define SN_GPIO_OUTPUT_SHIFT0 > +#define SN_GPIO_CTRL_REG 0x5F > +#define SN_GPIO_MUX_INPUT 0 > +#define SN_GPIO_MUX_OUTPUT 1 > +#define SN_GPIO_MUX_SPECIAL 2 > +#define SN_GPIO_MUX_MASK0x3 > #define SN_AUX_WDATA_REG(x) (0x64 + (x)) > #define SN_AUX_ADDR_19_16_REG0x74 > #define SN_AUX_ADDR_15_8_REG 0x75 > @@ -88,6 +98,35 @@ > > #define SN_REGULATOR_SUPPLY_NUM 4 > > +#define SN_NUM_GPIOS 4 > +#define SN_GPIO_PHYSICAL_OFFSET 1 > + > +/** > + * struct ti_sn_bridge - Platform data for ti-sn65dsi86 driver. > + * @dev: Pointer to our device. > + * @regmap: Regmap for accessing i2c. > + * @aux: Our aux channel. > + * @bridge: Our bridge. > + * @connector:Our connector. > + * @debugfs: Used for managing our debugfs. > + * @host_node:Remote DSI node. > + * @dsi: Our MIPI DSI source. > + * @refclk: Our reference clock. > + * @panel:Our panel. > + * @enable_gpio: The GPIO we toggle to enable the bridge. > + * @supplies: Data for bulk enabling/disabling our regulators. > + * @dp_lanes: Count of dp_lanes we're using. > + * > + * @gchip:If we expose our GPIOs, this is used. > + * @gchip_output: A cache of whether we've
[PATCH v3] mtd: rawnand: brcmnand: correctly verify erased pages
The current code checks that the whole OOB area is erased. This is a problem when JFFS2 cleanmarkers are added to the OOB, since it will fail due to the usable OOB bytes not being 0xff. Correct this by only checking that data and ECC bytes aren't 0xff. Fixes: 02b88eea9f9c ("mtd: brcmnand: Add check for erased page bitflips") Signed-off-by: Álvaro Fernández Rojas --- v3: Fix commit log and merge nand_check_erased_ecc_chunk calls. v2: Add Fixes tag drivers/mtd/nand/raw/brcmnand/brcmnand.c | 19 ++- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c index e4e3ceeac38f..80fe01f03516 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c @@ -2018,8 +2018,9 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip, static int brcmstb_nand_verify_erased_page(struct mtd_info *mtd, struct nand_chip *chip, void *buf, u64 addr) { + struct mtd_oob_region oobecc; int i, sas; - void *oob = chip->oob_poi; + void *oob; int bitflips = 0; int page = addr >> chip->page_shift; int ret; @@ -2035,11 +2036,19 @@ static int brcmstb_nand_verify_erased_page(struct mtd_info *mtd, if (ret) return ret; - for (i = 0; i < chip->ecc.steps; i++, oob += sas) { + for (i = 0; i < chip->ecc.steps; i++) { ecc_chunk = buf + chip->ecc.size * i; - ret = nand_check_erased_ecc_chunk(ecc_chunk, - chip->ecc.size, - oob, sas, NULL, 0, + + if (mtd->ooblayout->ecc(mtd, i, )) { + oob = NULL; + oobecc.length = 0; + } else { + oob = chip->oob_poi + oobecc.offset; + } + + ret = nand_check_erased_ecc_chunk(ecc_chunk, chip->ecc.size, + oob, oobecc.length, + NULL, 0, chip->ecc.strength); if (ret < 0) return ret; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 2/5] dt-bindings: display: panel: Add ilitek ili9341 panel bindings
From: dillon min Add documentation for "ilitek,ili9341" panel. Signed-off-by: dillon min --- Changes: V3: change compatible to st,sf-tc240t-9370-t, match #vendor,#lcd_module style V2: verifyied with make dt_binding_check V1: none .../bindings/display/panel/ilitek,ili9341.yaml | 68 ++ 1 file changed, 68 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml diff --git a/Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml b/Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml new file mode 100644 index 000..9f694d8 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/ilitek,ili9341.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Ilitek-9341 Display Panel + +maintainers: + - Dillon Min + +description: | + Ilitek ILI9341 TFT panel driver with SPI control bus + This is a driver for 320x240 TFT panels, accepting a rgb input + streams with 16 bits or 18 bits. + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: +items: + - enum: + # ili9341 240*320 Color on stm32f429-disco board +- st,sf-tc240t-9370-t + - const: ilitek,ili9341 + + reg: true + + dc-gpios: +maxItems: 1 +description: Display data/command selection (D/CX) + + spi-3wire: true + + spi-max-frequency: +const: 1000 + + port: true + +additionalProperties: false + +required: + - compatible + - reg + - dc-gpios + - port + +examples: + - |+ +spi { +#address-cells = <1>; +#size-cells = <0>; +panel: display@0 { + compatible = "st,sf-tc240t-9370-t", "ilitek,ili9341"; + reg = <0>; + spi-3wire; + spi-max-frequency = <1000>; + dc-gpios = < 13 0>; + port { + panel_in: endpoint { + remote-endpoint = <_out>; + }; + }; + }; +}; +... + -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v7 07/15] Documentation: power: update Energy Model description
The Energy Model framework supports also other devices than CPUs. Update related information and add description for the new usage. Acked-by: Daniel Lezcano Signed-off-by: Lukasz Luba --- Documentation/power/energy-model.rst | 135 +++ 1 file changed, 75 insertions(+), 60 deletions(-) diff --git a/Documentation/power/energy-model.rst b/Documentation/power/energy-model.rst index 90a345d57ae9..a6fb986abe3c 100644 --- a/Documentation/power/energy-model.rst +++ b/Documentation/power/energy-model.rst @@ -1,15 +1,17 @@ - -Energy Model of CPUs - +.. SPDX-License-Identifier: GPL-2.0 + +=== +Energy Model of devices +=== 1. Overview --- The Energy Model (EM) framework serves as an interface between drivers knowing -the power consumed by CPUs at various performance levels, and the kernel +the power consumed by devices at various performance levels, and the kernel subsystems willing to use that information to make energy-aware decisions. -The source of the information about the power consumed by CPUs can vary greatly +The source of the information about the power consumed by devices can vary greatly from one platform to another. These power costs can be estimated using devicetree data in some cases. In others, the firmware will know better. Alternatively, userspace might be best positioned. And so on. In order to avoid @@ -25,7 +27,7 @@ framework, and interested clients reading the data from it:: +---+ +-+ +---+ | Thermal (IPA) | | Scheduler (EAS) | | Other | +---+ +-+ +---+ - | | em_pd_energy()| + | | em_cpu_energy() | | | em_cpu_get() | +-+ | +-+ | | | @@ -35,7 +37,7 @@ framework, and interested clients reading the data from it:: | Framework | +-+ ^ ^ ^ - | | | em_register_perf_domain() + | | | em_dev_register_perf_domain() +--+ | +-+ | | | +---+ +---+ +--+ @@ -47,12 +49,12 @@ framework, and interested clients reading the data from it:: | Device Tree | | Firmware| | ? | +--+ +---+ +--+ -The EM framework manages power cost tables per 'performance domain' in the -system. A performance domain is a group of CPUs whose performance is scaled -together. Performance domains generally have a 1-to-1 mapping with CPUFreq -policies. All CPUs in a performance domain are required to have the same -micro-architecture. CPUs in different performance domains can have different -micro-architectures. +In case of CPU devices the EM framework manages power cost tables per +'performance domain' in the system. A performance domain is a group of CPUs +whose performance is scaled together. Performance domains generally have a +1-to-1 mapping with CPUFreq policies. All CPUs in a performance domain are +required to have the same micro-architecture. CPUs in different performance +domains can have different micro-architectures. 2. Core APIs @@ -70,14 +72,16 @@ CONFIG_ENERGY_MODEL must be enabled to use the EM framework. Drivers are expected to register performance domains into the EM framework by calling the following API:: - int em_register_perf_domain(cpumask_t *span, unsigned int nr_states, - struct em_data_callback *cb); + int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, + struct em_data_callback *cb, cpumask_t *cpus); -Drivers must specify the CPUs of the performance domains using the cpumask -argument, and provide a callback function returning tuples -for each capacity state. The callback function provided by the driver is free +Drivers must provide a callback function returning tuples +for each performance state. The callback function provided by the driver is free to fetch data from any relevant location (DT, firmware, ...), and by any mean -deemed necessary. See Section 3. for an example of driver implementing this +deemed necessary. Only for CPU devices, drivers must specify the CPUs of the +performance domains using cpumask. For other devices than CPUs the last +argument must be set to NULL. +See Section 3. for an example of driver implementing this callback, and kernel/power/energy_model.c for further documentation on this API. @@ -85,13 +89,20 @@ API. 2.3 Accessing performance domains
[PATCH v7 06/15] PM / EM: change name of em_pd_energy to em_cpu_energy
Energy Model framework supports now other devices than CPUs. Refactor some of the functions in order to prevent wrong usage. The old function em_pd_energy has to generic name. It must not be used without proper cpumask pointer, which is possible only for CPU devices. Thus, rename it and add proper description to warn of potential wrong usage for other devices. Acked-by: Daniel Lezcano Signed-off-by: Lukasz Luba --- include/linux/energy_model.h | 11 --- kernel/sched/fair.c | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h index 6b56ae6c6a89..c92e3ee15245 100644 --- a/include/linux/energy_model.h +++ b/include/linux/energy_model.h @@ -82,15 +82,20 @@ int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, void em_dev_unregister_perf_domain(struct device *dev); /** - * em_pd_energy() - Estimates the energy consumed by the CPUs of a perf. domain + * em_cpu_energy() - Estimates the energy consumed by the CPUs of a + performance domain * @pd : performance domain for which energy has to be estimated * @max_util : highest utilization among CPUs of the domain * @sum_util : sum of the utilization of all CPUs in the domain * + * This function must be used only for CPU devices. There is no validation, + * i.e. if the EM is a CPU type and has cpumask allocated. It is called from + * the scheduler code quite frequently and that is why there is not checks. + * * Return: the sum of the energy consumed by the CPUs of the domain assuming * a capacity state satisfying the max utilization of the domain. */ -static inline unsigned long em_pd_energy(struct em_perf_domain *pd, +static inline unsigned long em_cpu_energy(struct em_perf_domain *pd, unsigned long max_util, unsigned long sum_util) { unsigned long freq, scale_cpu; @@ -195,7 +200,7 @@ static inline struct em_perf_domain *em_pd_get(struct device *dev) { return NULL; } -static inline unsigned long em_pd_energy(struct em_perf_domain *pd, +static inline unsigned long em_cpu_energy(struct em_perf_domain *pd, unsigned long max_util, unsigned long sum_util) { return 0; diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index b3bb4d6e49c3..7700e97af52f 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -6468,7 +6468,7 @@ compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd) max_util = max(max_util, cpu_util); } - return em_pd_energy(pd->em_pd, max_util, sum_util); + return em_cpu_energy(pd->em_pd, max_util, sum_util); } /* -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 5/5] drm/panel: Add ilitek ili9341 driver
From: dillon min Currently, we can use tinydrm ili9341 driver to drive ili9341 panel by spi interface (both register configuration and video) ili9341 have parallel and mcu interface as well, we extend the support to parallel rgb interface with DRM_MODE_CONNECTOR_DPI this driver can work as parallel rgb or serial spi mode by different dts binding. for serial spi interface dts binding configuration, refer to: Documentation/devicetree/bindings/display/ilitek,ili9341.txt Signed-off-by: dillon min --- Changes: V3: 1 Add support for original dts binding "adafruit,yx240qv29", merged from tiny/ili9341.c, which is serial spi interface for register configuration and video trasfer. 2 change the dts binding to st,sf-tc240t-9370-t for parallel rgb interface. V2: none V1: Add support for parallel rgb interface drivers/gpu/drm/panel/Kconfig| 12 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 700 +++ 3 files changed, 713 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-ilitek-ili9341.c diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index a1723c1..c938bee 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -95,6 +95,18 @@ config DRM_PANEL_ILITEK_IL9322 Say Y here if you want to enable support for Ilitek IL9322 QVGA (320x240) RGB, YUV and ITU-T BT.656 panels. +config DRM_PANEL_ILITEK_ILI9341 + tristate "Ilitek ILI9341 240x320 QVGA panels" + depends on OF && SPI + depends on DRM_KMS_HELPER + depends on DRM_KMS_CMA_HELPER + depends on BACKLIGHT_CLASS_DEVICE + select DRM_MIPI_DBI + help + Say Y here if you want to enable support for Ilitek IL9341 + QVGA (240x320) RGB panels. support serial & parallel rgb + interface. + config DRM_PANEL_ILITEK_ILI9881C tristate "Ilitek ILI9881C-based panels" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 96a883c..16947d7 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_DRM_PANEL_ELIDA_KD35T133) += panel-elida-kd35t133.o obj-$(CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02) += panel-feixin-k101-im2ba02.o obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += panel-feiyang-fy07024di26a30d.o obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o +obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9341) += panel-ilitek-ili9341.o obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c new file mode 100644 index 000..17339db --- /dev/null +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c @@ -0,0 +1,700 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Ilitek ILI9341 TFT LCD drm_panel driver. + * + * This panel can be configured to support: + * - 16-bit parallel RGB interface + * - 18-bit parallel RGB interface + * + * Copyright (C) 2020 Dillon Min + * Derived from drivers/drm/gpu/panel/panel-ilitek-ili9322.c + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define ILI9341_SLEEP_OUT0x11 /* Sleep out register */ +#define ILI9341_GAMMA0x26 /* Gamma register */ +#define ILI9341_DISPLAY_OFF 0x28 /* Display off register */ +#define ILI9341_DISPLAY_ON 0x29 /* Display on register */ +#define ILI9341_COLUMN_ADDR 0x2a /* Colomn address register */ +#define ILI9341_PAGE_ADDR0x2b /* Page address register */ +#define ILI9341_GRAM 0x2c /* GRAM register */ +#define ILI9341_MAC 0x36 /* Memory Access Control register*/ +#define ILI9341_PIXEL_FORMAT 0x3A /* Pixel Format register */ +#define ILI9341_RGB_INTERFACE0xb0 /* RGB Interface Signal Control */ +#define ILI9341_FRC 0xb1 /* Frame Rate Control register */ +#define ILI9341_DFC 0xb6 /* Display Function Control +* register +*/ +#define ILI9341_POWER1 0xc0 /* Power Control 1 register */ +#define ILI9341_POWER2 0xc1 /* Power Control 2 register */ +#define ILI9341_VCOM10xc5 /* VCOM Control 1 register */ +#define ILI9341_VCOM20xc7 /* VCOM Control 2 register */ +#define ILI9341_POWERA 0xcb /* Power control A register */ +#define ILI9341_POWERB 0xcf /* Power control B register */ +#define ILI9341_PGAMMA
[PATCH v7 14/15] thermal: devfreq_cooling: update license to use SPDX
Change the license headers and use SPDX standard. Signed-off-by: Lukasz Luba --- drivers/thermal/devfreq_cooling.c | 12 ++-- include/linux/devfreq_cooling.h | 12 ++-- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/drivers/thermal/devfreq_cooling.c b/drivers/thermal/devfreq_cooling.c index 79dcef3dbeeb..77d996fd82d2 100644 --- a/drivers/thermal/devfreq_cooling.c +++ b/drivers/thermal/devfreq_cooling.c @@ -1,17 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * devfreq_cooling: Thermal cooling device implementation for devices using * devfreq * - * Copyright (C) 2014-2015 ARM Limited - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Copyright (C) 2014-2020 ARM Limited * * TODO: *- If OPPs are added or removed after devfreq cooling has diff --git a/include/linux/devfreq_cooling.h b/include/linux/devfreq_cooling.h index 613678ce23df..1f5c07c78f0f 100644 --- a/include/linux/devfreq_cooling.h +++ b/include/linux/devfreq_cooling.h @@ -1,17 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * devfreq_cooling: Thermal cooling device implementation for devices using * devfreq * - * Copyright (C) 2014-2015 ARM Limited - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Copyright (C) 2014-2020 ARM Limited */ #ifndef __DEVFREQ_COOLING_H__ -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v7 02/15] PM / EM: introduce em_dev_register_perf_domain function
Add now function in the Energy Model framework which is going to support new devices. This function will help in transition and make it smoother. For now it still checks if the cpumask is a valid pointer, which will be removed later when the new structures and infrastructure will be ready. Acked-by: Daniel Lezcano Signed-off-by: Lukasz Luba --- include/linux/energy_model.h | 13 ++-- kernel/power/energy_model.c | 40 ++-- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h index fe336a9eb5d4..7c048df98447 100644 --- a/include/linux/energy_model.h +++ b/include/linux/energy_model.h @@ -2,6 +2,7 @@ #ifndef _LINUX_ENERGY_MODEL_H #define _LINUX_ENERGY_MODEL_H #include +#include #include #include #include @@ -42,7 +43,7 @@ struct em_perf_domain { #define em_span_cpus(em) (to_cpumask((em)->cpus)) #ifdef CONFIG_ENERGY_MODEL -#define EM_CPU_MAX_POWER 0x +#define EM_MAX_POWER 0x struct em_data_callback { /** @@ -59,7 +60,7 @@ struct em_data_callback { * and frequency. * * The power is the one of a single CPU in the domain, expressed in -* milli-watts. It is expected to fit in the [0, EM_CPU_MAX_POWER] +* milli-watts. It is expected to fit in the [0, EM_MAX_POWER] * range. * * Return 0 on success. @@ -71,6 +72,8 @@ struct em_data_callback { struct em_perf_domain *em_cpu_get(int cpu); int em_register_perf_domain(cpumask_t *span, unsigned int nr_states, struct em_data_callback *cb); +int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, + struct em_data_callback *cb, cpumask_t *span); /** * em_pd_energy() - Estimates the energy consumed by the CPUs of a perf. domain @@ -174,6 +177,12 @@ static inline int em_register_perf_domain(cpumask_t *span, { return -EINVAL; } +static inline +int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, + struct em_data_callback *cb, cpumask_t *span) +{ + return -EINVAL; +} static inline struct em_perf_domain *em_cpu_get(int cpu) { return NULL; diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c index 9892d548a0fa..875b163e54ab 100644 --- a/kernel/power/energy_model.c +++ b/kernel/power/energy_model.c @@ -125,7 +125,7 @@ static struct em_perf_domain *em_create_pd(cpumask_t *span, int nr_states, * The power returned by active_state() is expected to be * positive, in milli-watts and to fit into 16 bits. */ - if (!power || power > EM_CPU_MAX_POWER) { + if (!power || power > EM_MAX_POWER) { pr_err("pd%d: invalid power: %lu\n", cpu, power); goto free_ps_table; } @@ -183,10 +183,13 @@ struct em_perf_domain *em_cpu_get(int cpu) EXPORT_SYMBOL_GPL(em_cpu_get); /** - * em_register_perf_domain() - Register the Energy Model of a performance domain - * @span : Mask of CPUs in the performance domain + * em_dev_register_perf_domain() - Register the Energy Model (EM) for a device + * @dev: Device for which the EM is to register * @nr_states : Number of performance states to register * @cb : Callback functions providing the data of the Energy Model + * @span : Pointer to cpumask_t, which in case of a CPU device is + * obligatory. It can be taken from i.e. 'policy->cpus'. For other + * type of devices this should be set to NULL. * * Create Energy Model tables for a performance domain using the callbacks * defined in cb. @@ -196,14 +199,14 @@ EXPORT_SYMBOL_GPL(em_cpu_get); * * Return 0 on success */ -int em_register_perf_domain(cpumask_t *span, unsigned int nr_states, - struct em_data_callback *cb) +int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, + struct em_data_callback *cb, cpumask_t *span) { unsigned long cap, prev_cap = 0; struct em_perf_domain *pd; int cpu, ret = 0; - if (!span || !nr_states || !cb) + if (!dev || !span || !nr_states || !cb) return -EINVAL; /* @@ -255,4 +258,29 @@ int em_register_perf_domain(cpumask_t *span, unsigned int nr_states, return ret; } +EXPORT_SYMBOL_GPL(em_dev_register_perf_domain); + +/** + * em_register_perf_domain() - Register the Energy Model of a performance domain + * @span : Mask of CPUs in the performance domain + * @nr_states : Number of capacity states to register + * @cb : Callback functions providing the data of the Energy Model + * + * Create Energy Model tables for a performance domain using the callbacks + * defined in cb. + *
[PATCH v3 0/2] mtd: rawnand: brcmnand: improve hamming oob layout
These patches improve the OOB hamming layout by reducing the number of oob sections and correctly v3: invert patch order. v2: extend original comment and correctly skip byte 6 for small-page. Álvaro Fernández Rojas (2): mtd: rawnand: brcmnand: fix hamming oob layout mtd: rawnand: brcmnand: improve hamming oob layout drivers/mtd/nand/raw/brcmnand/brcmnand.c | 34 +--- 1 file changed, 18 insertions(+), 16 deletions(-) -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v7 15/15] drm/panfrost: Register devfreq cooling and attempt to add Energy Model
Register devfreq cooling device and attempt to register Energy Model. This will add the devfreq device to the Energy Model framework. It will create a dedicated and unified data structures used i.e. in thermal framework. The last NULL parameter indicates that the power model is simplified and created based on DT 'dynamic-power-coefficient', voltage and frequency. Reviewed-by: Steven Price Reviewed-by: Alyssa Rosenzweig Signed-off-by: Lukasz Luba --- drivers/gpu/drm/panfrost/panfrost_devfreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c index 413987038fbf..8759a73db153 100644 --- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c +++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c @@ -105,7 +105,7 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) } pfdev->devfreq.devfreq = devfreq; - cooling = of_devfreq_cooling_register(dev->of_node, devfreq); + cooling = devfreq_cooling_em_register(devfreq, NULL); if (IS_ERR(cooling)) DRM_DEV_INFO(dev, "Failed to register cooling device\n"); else -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC v2 0/1] drm/connector: Add support for privacy-screen properties
Hi, On 5/11/20 9:55 PM, Rajat Jain wrote: Hi Hans, On Mon, May 11, 2020 at 10:47 AM Hans de Goede mailto:hdego...@redhat.com>> wrote: Hi All, This RFC takes Rajat's earlier patch for adding privacy-screen properties infra to drm_connector.c and then adds the results of the discussion from the "RFC: Drm-connector properties managed by another driver / privacy screen support" mail thread on top, hence the v2. Thank you so much for doing this. I was following the said discussion and eventually it became quite complex for me to understand and follow :-) I hope the new doc text makes things clear again? The most important thing here is big kernel-doc comment which gets added in the first patch-chunk modifying drm_connector.c, this summarizes, or at least tries to summarize, the conclusions of our previous discussion on the userspace API and lays down the ground rules for how the 2 new "privacy-screen sw-state" and "privacy-screen hw-state" properties are to be used both from the driver side as well as from the userspace side. Other then that this modifies Rajat's patch to add 2 properties instead of one, without much other changes. Rajat, perhaps you can do a new version of your patch-set integration / using this version of the properties and then if everyone is ok with the proposed userspace API Jani can hopefully merge the whole set through the i915 tree sometime during the 5.9 cycle. SGTM. I have actually moved to working on something else now, so I will most likely wait for this patch to get merged, before rebasing my other / remaining patches on top of that. We have the rule that code like this will not be merged until it has at least one in kernel user. I plan to eventually use this too, but that is still a while away as I first need to write a lcdshadow subsystem which the thinkpad_acpi code can then use to register a lcdshadow device; and when that all is in place, then I can hook it up on the drm code. So since Jani said your patch-set was more or less ready I think it would be best if you add my version of this to your patch-set and then post a new version of your patch-set. But first let me do a v3 addressing the remarks on doc text. Note I will wait a bit before sending out v3 to see if I get more feedback. Regards, Hans Thanks & Best Regards, Rajat This RFC takes Rajat's earlier patch for adding privacy-screen properties infra to drm_connector.c and then adds the results of the discussion from the "RFC: Drm-connector properties managed by another driver / privacy screen support" mail thread on top, hence the v2. The most important thing here is big kernel-doc comment which gets added in the first patch-chunk modifying drm_connector.c, this summarizes, or at least tries to summarize, the conclusions of our previous discussion on the userspace API and lays down the ground rules for how the 2 new "privacy-screen sw-state" and "privacy-screen hw-state" properties are to be used both from the driver side as well as from the userspace side. Other then that this modifies Rajat's patch to add 2 properties instead of one, without much other changes. Rajat, perhaps you can do a new version of your patch-set integration / using this version of the properties and then if everyone is ok with the proposed userspace API Jani can hopefully merge the whole set through the i915 tree sometime during the 5.9 cycle. Regards, Hans p.s. I plan to start working on the lcdshadow subsystem next. As discussed the plan for this subsystem is to allow drivers outside of the DRM subsys, such as for example the thinkpad_acpi driver, to register a lcdshadow device, which DRM drivers can then get a reference to and use to implement these properties. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 2/3] drm/i915/dp: Attach and set drm connector VRR property
From: Aditya Swarup This function sets the VRR property for connector based on the platform support, EDID monitor range and DP sink DPCD capability of outputing video without msa timing information. v5: * Fix the vrr prop not being set in kernel (Manasi) * Unset the prop on connector disconnect (Manasi) v4: * Rebase (Mansi) v3: * intel_dp_is_vrr_capable can be used for debugfs, make it non static (Manasi) v2: * Just set this in intel_dp_get_modes instead of new hook (Jani) Cc: Ville Syrjälä Cc: Jani Nikula Signed-off-by: Aditya Swarup Signed-off-by: Manasi Navare --- drivers/gpu/drm/i915/display/intel_dp.c | 27 + drivers/gpu/drm/i915/display/intel_dp.h | 2 ++ 2 files changed, 29 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 67723dede1d1..8957a9f50f0e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -6153,6 +6153,9 @@ intel_dp_detect(struct drm_connector *connector, if (status == connector_status_disconnected) { memset(_dp->compliance, 0, sizeof(intel_dp->compliance)); memset(intel_dp->dsc_dpcd, 0, sizeof(intel_dp->dsc_dpcd)); + /*Reset the immutable VRR Capable property */ + drm_connector_set_vrr_capable_property(connector, + false); if (intel_dp->is_mst) { drm_dbg_kms(_priv->drm, @@ -6260,6 +6263,23 @@ intel_dp_force(struct drm_connector *connector) intel_display_power_put(dev_priv, aux_domain, wakeref); } +bool intel_dp_is_vrr_capable(struct drm_connector *connector) +{ + struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector)); + const struct drm_display_info *info = >display_info; + struct drm_i915_private *dev_priv = to_i915(connector->dev); + + /* +* DP Sink is capable of Variable refresh video timings if +* Ignore MSA bit is set in DPCD. +* EDID monitor range also should be atleast 10 for reasonable +* Adaptive sync/ VRR end user experience. +*/ + return INTEL_GEN(dev_priv) >= 12 && + drm_dp_sink_can_do_video_without_timing_msa(intel_dp->dpcd) && + info->monitor_range.max_vfreq - info->monitor_range.min_vfreq > 10; +} + static int intel_dp_get_modes(struct drm_connector *connector) { struct intel_connector *intel_connector = to_intel_connector(connector); @@ -6268,6 +6288,10 @@ static int intel_dp_get_modes(struct drm_connector *connector) edid = intel_connector->detect_edid; if (edid) { int ret = intel_connector_update_modes(connector, edid); + + if (intel_dp_is_vrr_capable(connector)) + drm_connector_set_vrr_capable_property(connector, + true); if (ret) return ret; } @@ -7354,6 +7378,9 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect connector->state->scaling_mode = DRM_MODE_SCALE_ASPECT; } + + if (INTEL_GEN(dev_priv) >= 12) + drm_connector_attach_vrr_capable_property(connector); } static void intel_dp_init_panel_power_timestamps(struct intel_dp *intel_dp) diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 6659ce15a693..aa7c1f530d5e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -14,6 +14,7 @@ enum pipe; enum port; struct drm_connector_state; struct drm_encoder; +struct drm_connector; struct drm_i915_private; struct drm_modeset_acquire_ctx; struct intel_connector; @@ -119,6 +120,7 @@ void intel_dp_set_infoframes(struct intel_encoder *encoder, bool enable, const struct drm_connector_state *conn_state); bool intel_digital_port_connected(struct intel_encoder *encoder); void intel_dp_process_phy_request(struct intel_dp *intel_dp); +bool intel_dp_is_vrr_capable(struct drm_connector *connector); static inline unsigned int intel_dp_unused_lane_mask(int lane_count) { -- 2.19.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 3/3] drm/i915/dp: Expose connector VRR info via debugfs
From: Bhanuprakash Modem [Why] It's useful to know the min and max vrr range for IGT testing. [How] Expose the min and max vfreq for the connector via a debugfs file on the connector, "i915_vrr_info". Example usage: cat /sys/kernel/debug/dri/0/DP-1/i915_vrr_info v5: * Rename to vrr_range to match AMD debugfs v4: * Rebase v3: * Remove the unnecessary debug print (Manasi) v2: * Fix the typo in max_vfreq (Manasi) * Change the name of node to i915_vrr_info so we can add other vrr info for more debug info (Manasi) * Change the VRR capable to display Yes or No (Manasi) * Fix indentation checkpatch errors (Manasi) Signed-off-by: Bhanuprakash Modem Signed-off-by: Manasi Navare Cc: Jani Nikula Cc: Ville Syrjälä Tested-by: Manasi Navare --- .../drm/i915/display/intel_display_debugfs.c | 22 ++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 70525623bcdf..a0d680c13e0d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -2185,6 +2185,21 @@ static const struct file_operations i915_dsc_fec_support_fops = { .write = i915_dsc_fec_support_write }; +static int vrr_range_show(struct seq_file *m, void *data) +{ + struct drm_connector *connector = m->private; + + if (connector->status != connector_status_connected) + return -ENODEV; + + seq_printf(m, "Vrr_capable: %s\n", yesno(intel_dp_is_vrr_capable(connector))); + seq_printf(m, "Min: %u\n", (u8)connector->display_info.monitor_range.min_vfreq); + seq_printf(m, "Max: %u\n", (u8)connector->display_info.monitor_range.max_vfreq); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(vrr_range); + /** * intel_connector_debugfs_add - add i915 specific connector debugfs files * @connector: pointer to a registered drm_connector @@ -2219,10 +2234,15 @@ int intel_connector_debugfs_add(struct drm_connector *connector) if (INTEL_GEN(dev_priv) >= 10 && (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort || -connector->connector_type == DRM_MODE_CONNECTOR_eDP)) +connector->connector_type == DRM_MODE_CONNECTOR_eDP)) { debugfs_create_file("i915_dsc_fec_support", S_IRUGO, root, connector, _dsc_fec_support_fops); + if (INTEL_GEN(dev_priv) >= 12) + debugfs_create_file("vrr_range", S_IRUGO, + root, connector, _range_fops); + } + /* Legacy panels doesn't lpsp on any platform */ if ((INTEL_GEN(dev_priv) >= 9 || IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) && -- 2.19.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 1/3] drm/dp: DRM DP helper for reading Ignore MSA from DPCD
DP sink device sets the Ignore MSA bit in its DP_DOWNSTREAM_PORT_COUNT register to indicate its ability to ignore the MSA video timing parameters and its ability to support seamless video timing change over a range of timing exposed by DisplayID and EDID. This is required for the sink to indicate that it is Adaptive sync capable. v3: * Fi the typo in commit message (Manasi) v2: * Rename to describe what the function does (Jani Nikula) Cc: Jani Nikula Cc: Ville Syrjälä Cc: Harry Wentland Cc: Nicholas Kazlauskas Signed-off-by: Manasi Navare Reviewed-by: Harry Wentland --- include/drm/drm_dp_helper.h | 8 1 file changed, 8 insertions(+) diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 6c4b53dcb851..d43b5c9705d4 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -1454,6 +1454,14 @@ drm_dp_alternate_scrambler_reset_cap(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) DP_ALTERNATE_SCRAMBLER_RESET_CAP; } +/* Ignore MSA timing for Adaptive Sync support on DP 1.4 */ +static inline bool +drm_dp_sink_can_do_video_without_timing_msa(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) +{ + return dpcd[DP_DOWN_STREAM_PORT_COUNT] & + DP_MSA_TIMING_PAR_IGNORED; +} + /* * DisplayPort AUX channel */ -- 2.19.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v4 1/6] drm/bridge: ti-sn65dsi86: Export bridge GPIOs to Linux
On Thu, May 7, 2020 at 4:39 PM Doug Anderson wrote: > One suggestion that came off-list is to change the code to make the > numbering match up better with the datasheet. Right now if you want > GPIO 2 you have to refer to it like: > > hpd-gpios = <_bridge 1 GPIO_ACTIVE_HIGH>; > > That's because the code right now numbers things starting at 0 even if > the datasheet numbers things starting at 1. This is the hallmark of mixed-mode IC engineers at work. They are at heart analog IC designers so of course they enumerate everything starting at 1. Digital IC designers are like programmers and start on 0. Never the twain shall meet... Yours, Linus Walleij ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 1/6] drm/bridge: ti-sn65dsi86: Export bridge GPIOs to Linux
On Thu, May 7, 2020 at 11:35 PM Douglas Anderson wrote: > The ti-sn65dsi86 MIPI DSI to eDP bridge chip has 4 pins on it that can > be used as GPIOs in a system. Each pin can be configured as input, > output, or a special function for the bridge chip. These are: > - GPIO1: SUSPEND Input > - GPIO2: DSIA VSYNC > - GPIO3: DSIA HSYNC or VSYNC > - GPIO4: PWM > > Let's expose these pins as GPIOs. A few notes: > - Access to ti-sn65dsi86 is via i2c so we set "can_sleep". > - These pins can't be configured for IRQ. > - There are no programmable pulls or other fancy features. > - Keeping the bridge chip powered might be expensive. The driver is > setup such that if all used GPIOs are only inputs we'll power the > bridge chip on just long enough to read the GPIO and then power it > off again. Setting a GPIO as output will keep the bridge powered. > - If someone releases a GPIO we'll implicitly switch it to an input so > we no longer need to keep the bridge powered for it. > > Because of all of the above limitations we just need to implement a > bare-bones GPIO driver. The device tree bindings already account for > this device being a GPIO controller so we only need the driver changes > for it. > > NOTE: Despite the fact that these pins are nominally muxable I don't > believe it makes sense to expose them through the pinctrl interface as > well as the GPIO interface. The special functions are things that the > bridge chip driver itself would care about and it can just configure > the pins as needed. > > Signed-off-by: Douglas Anderson > Cc: Linus Walleij > Cc: Bartosz Golaszewski Looks good mostly! > + pdata->gchip.label = dev_name(pdata->dev); > + pdata->gchip.parent = pdata->dev; > + pdata->gchip.owner = THIS_MODULE; > + pdata->gchip.of_xlate = tn_sn_bridge_of_xlate; > + pdata->gchip.of_gpio_n_cells = 2; > + pdata->gchip.free = ti_sn_bridge_gpio_free; > + pdata->gchip.get_direction = ti_sn_bridge_gpio_get_direction; > + pdata->gchip.direction_input = ti_sn_bridge_gpio_direction_input; > + pdata->gchip.direction_output = ti_sn_bridge_gpio_direction_output; > + pdata->gchip.get = ti_sn_bridge_gpio_get; > + pdata->gchip.set = ti_sn_bridge_gpio_set; > + pdata->gchip.can_sleep = true; > + pdata->gchip.names = ti_sn_bridge_gpio_names; > + pdata->gchip.ngpio = SN_NUM_GPIOS; Please add: pdata->gchip.base = -1; So it is clear that you use dynamically assigned GPIO numbers, with that: Reviewed-by: Linus Walleij Yours, Linus Walleij ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v4 01/38] dma-mapping: add generic helpers for mapping sgtable objects
Hi Christoph, On 12.05.2020 14:18, Christoph Hellwig wrote: > On Tue, May 12, 2020 at 11:00:21AM +0200, Marek Szyprowski wrote: >> struct sg_table is a common structure used for describing a memory >> buffer. It consists of a scatterlist with memory pages and DMA addresses >> (sgl entry), as well as the number of scatterlist entries: CPU pages >> (orig_nents entry) and DMA mapped pages (nents entry). >> >> It turned out that it was a common mistake to misuse nents and orig_nents >> entries, calling DMA-mapping functions with a wrong number of entries or >> ignoring the number of mapped entries returned by the dma_map_sg >> function. >> >> To avoid such issues, lets introduce a common wrappers operating directly >> on the struct sg_table objects, which take care of the proper use of >> the nents and orig_nents entries. >> >> Signed-off-by: Marek Szyprowski >> --- >> For more information, see '[PATCH v4 00/38] DRM: fix struct sg_table nents >> vs. orig_nents misuse' thread: >> https://lore.kernel.org/dri-devel/20200512085710.14688-1-m.szyprow...@samsung.com/T/ >> --- >> include/linux/dma-mapping.h | 79 >> + >> 1 file changed, 79 insertions(+) >> >> diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h >> index b43116a..88f01cc 100644 >> --- a/include/linux/dma-mapping.h >> +++ b/include/linux/dma-mapping.h >> @@ -609,6 +609,85 @@ static inline void >> dma_sync_single_range_for_device(struct device *dev, >> return dma_sync_single_for_device(dev, addr + offset, size, dir); >> } >> >> +/** >> + * dma_map_sgtable - Map the given buffer for the DMA operations >> + * @dev:The device to perform a DMA operation >> + * @sgt:The sg_table object describing the buffer >> + * @dir:DMA direction >> + * @attrs: Optional DMA attributes for the map operation >> + * >> + * Maps a buffer described by a scatterlist stored in the given sg_table >> + * object for the @dir DMA operation by the @dev device. After success >> + * the ownership for the buffer is transferred to the DMA domain. One has >> + * to call dma_sync_sgtable_for_cpu() or dma_unmap_sgtable() to move the >> + * ownership of the buffer back to the CPU domain before touching the >> + * buffer by the CPU. >> + * Returns 0 on success or -EINVAL on error during mapping the buffer. >> + */ >> +static inline int dma_map_sgtable(struct device *dev, struct sg_table *sgt, >> +enum dma_data_direction dir, unsigned long attrs) >> +{ >> +int n = dma_map_sg_attrs(dev, sgt->sgl, sgt->orig_nents, dir, attrs); >> + >> +if (n > 0) { >> +sgt->nents = n; >> +return 0; >> +} >> +return -EINVAL; > Nit: code tend to be a tad easier to read if the the exceptional > condition is inside the branch block, so: > > if (n <= 0) > return -EINVAL; > sgt->nents = n; > return 0; > Indeed this version looks much better. I will resend it in a few minutes. > Otherwise this looks good to me: > > Reviewed-by: Christoph Hellwig > Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC] Remove AGP support from Radeon/Nouveau/TTM
On Tue, May 12, 2020 at 5:40 AM Karoly Balogh (Charlie/SGR) wrote: > > Hi, > > On Tue, 12 May 2020, Rui Salvaterra wrote: > > > > FWIW, on my last-generation PowerBook with RV350 (IIRC), there was a > > > big performance difference between AGP and PCI GART. The latter was > > > sort of usable for normal desktop operation, but not so much for > > > OpenGL apps (which were usable with AGP). > > > > I never really understood what were the issues with AGP on PowerPC > > (well, Apple, the only ones I've tested) machines. I mean, did OS X also > > disable AGP entirely, or did it have workarounds somewhere else on the > > stack nobody was able to figure out? > > I don't know about OS X, but I doubt there is a major/blocker hardware > issue, at least not one which affects every AGP machine. > > MorphOS' own Radeon driver uses the AGP facilities to some degree on all > AGP PowerPC Macs supported by that OS, which is from PMac AGP Graphics > (3,1) all the way up to the AGP G5 (7,3), including the various portables > and the Mac mini G4. For example it can utilize it to stream video data > directly from mainboard RAM, so you don't have to copy it with the CPU, > allowing reasonably good 720p h264 video playback on most systems above > the 1Ghz mark with the native MPlayer port. I'm sure the 3D part of the > driver also use it to some degree, given the performance improvement we > experienced when the AGP support was enabled (initially the system was > running without it), but to which extent I can't say. The problem is AGP doesn't support CPU cache snooping. Technically PCI must support coherent device access to system memory. Unsnooped access is an optional feature and some platforms may not support it at all. Unfortunately, AGP required unsnooped access. x8t generally provides a way to do this, but other platforms, not so much. I don't recall to what extent PowerPC supported this. The Linux DMA API doesn't really have a way to get uncached memory for DMA so there is that too. Windows and Mac may provide a way to do this depending on the platforms. What probably should have been done on AGP boards was to use both the AGP GART and the device GART. The former for uncached memory (if the platform supported it) and the latter for cached memory. That never happened. Alex ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC 16/17] drm/amdgpu: gpu recovery does full modesets
On Tue, May 12, 2020 at 9:17 AM Daniel Vetter wrote: > > On Tue, May 12, 2020 at 3:12 PM Alex Deucher wrote: > > > > On Tue, May 12, 2020 at 8:58 AM Daniel Vetter wrote: > > > > > > On Tue, May 12, 2020 at 08:54:45AM -0400, Alex Deucher wrote: > > > > On Tue, May 12, 2020 at 5:00 AM Daniel Vetter > > > > wrote: > > > > > > > > > > ... > > > > > > > > > > I think it's time to stop this little exercise. > > > > > > > > > > The lockdep splat, for the record: > > > > > > > > > > [ 132.583381] == > > > > > [ 132.584091] WARNING: possible circular locking dependency detected > > > > > [ 132.584775] 5.7.0-rc3+ #346 Tainted: GW > > > > > [ 132.585461] -- > > > > > [ 132.586184] kworker/2:3/865 is trying to acquire lock: > > > > > [ 132.586857] c9677c70 (crtc_ww_class_acquire){+.+.}-{0:0}, > > > > > at: drm_atomic_helper_suspend+0x38/0x120 [drm_kms_helper] > > > > > [ 132.587569] > > > > >but task is already holding lock: > > > > > [ 132.589044] 82318c80 (dma_fence_map){}-{0:0}, at: > > > > > drm_sched_job_timedout+0x25/0xf0 [gpu_sched] > > > > > [ 132.589803] > > > > >which lock already depends on the new lock. > > > > > > > > > > [ 132.592009] > > > > >the existing dependency chain (in reverse order) is: > > > > > [ 132.593507] > > > > >-> #2 (dma_fence_map){}-{0:0}: > > > > > [ 132.595019]dma_fence_begin_signalling+0x50/0x60 > > > > > [ 132.595767]drm_atomic_helper_commit+0xa1/0x180 > > > > > [drm_kms_helper] > > > > > [ 132.596567]drm_client_modeset_commit_atomic+0x1ea/0x250 > > > > > [drm] > > > > > [ 132.597420]drm_client_modeset_commit_locked+0x55/0x190 > > > > > [drm] > > > > > [ 132.598178]drm_client_modeset_commit+0x24/0x40 [drm] > > > > > [ 132.598948] > > > > > drm_fb_helper_restore_fbdev_mode_unlocked+0x4b/0xa0 [drm_kms_helper] > > > > > [ 132.599738]drm_fb_helper_set_par+0x30/0x40 [drm_kms_helper] > > > > > [ 132.600539]fbcon_init+0x2e8/0x660 > > > > > [ 132.601344]visual_init+0xce/0x130 > > > > > [ 132.602156]do_bind_con_driver+0x1bc/0x2b0 > > > > > [ 132.602970]do_take_over_console+0x115/0x180 > > > > > [ 132.603763]do_fbcon_takeover+0x58/0xb0 > > > > > [ 132.604564]register_framebuffer+0x1ee/0x300 > > > > > [ 132.605369] > > > > > __drm_fb_helper_initial_config_and_unlock+0x36e/0x520 [drm_kms_helper] > > > > > [ 132.606187]amdgpu_fbdev_init+0xb3/0xf0 [amdgpu] > > > > > [ 132.607032]amdgpu_device_init.cold+0xe90/0x1677 [amdgpu] > > > > > [ 132.607862]amdgpu_driver_load_kms+0x5a/0x200 [amdgpu] > > > > > [ 132.608697]amdgpu_pci_probe+0xf7/0x180 [amdgpu] > > > > > [ 132.609511]local_pci_probe+0x42/0x80 > > > > > [ 132.610324]pci_device_probe+0x104/0x1a0 > > > > > [ 132.611130]really_probe+0x147/0x3c0 > > > > > [ 132.611939]driver_probe_device+0xb6/0x100 > > > > > [ 132.612766]device_driver_attach+0x53/0x60 > > > > > [ 132.613593]__driver_attach+0x8c/0x150 > > > > > [ 132.614419]bus_for_each_dev+0x7b/0xc0 > > > > > [ 132.615249]bus_add_driver+0x14c/0x1f0 > > > > > [ 132.616071]driver_register+0x6c/0xc0 > > > > > [ 132.616902]do_one_initcall+0x5d/0x2f0 > > > > > [ 132.617731]do_init_module+0x5c/0x230 > > > > > [ 132.618560]load_module+0x2981/0x2bc0 > > > > > [ 132.619391]__do_sys_finit_module+0xaa/0x110 > > > > > [ 132.620228]do_syscall_64+0x5a/0x250 > > > > > [ 132.621064]entry_SYSCALL_64_after_hwframe+0x49/0xb3 > > > > > [ 132.621903] > > > > >-> #1 (crtc_ww_class_mutex){+.+.}-{3:3}: > > > > > [ 132.623587]__ww_mutex_lock.constprop.0+0xcc/0x10c0 > > > > > [ 132.624448]ww_mutex_lock+0x43/0xb0 > > > > > [ 132.625315]drm_modeset_lock+0x44/0x120 [drm] > > > > > [ 132.626184]drmm_mode_config_init+0x2db/0x8b0 [drm] > > > > > [ 132.627098]amdgpu_device_init.cold+0xbd1/0x1677 [amdgpu] > > > > > [ 132.628007]amdgpu_driver_load_kms+0x5a/0x200 [amdgpu] > > > > > [ 132.628920]amdgpu_pci_probe+0xf7/0x180 [amdgpu] > > > > > [ 132.629804]local_pci_probe+0x42/0x80 > > > > > [ 132.630690]pci_device_probe+0x104/0x1a0 > > > > > [ 132.631583]really_probe+0x147/0x3c0 > > > > > [ 132.632479]driver_probe_device+0xb6/0x100 > > > > > [ 132.633379]device_driver_attach+0x53/0x60 > > > > > [ 132.634275]__driver_attach+0x8c/0x150 > > > > > [ 132.635170]bus_for_each_dev+0x7b/0xc0 > > > > > [ 132.636069]bus_add_driver+0x14c/0x1f0 > > > > > [ 132.636974]driver_register+0x6c/0xc0 > > > > > [ 132.637870]do_one_initcall+0x5d/0x2f0 > > > > > [ 132.638765]
Re: [RFC 16/17] drm/amdgpu: gpu recovery does full modesets
On Tue, May 12, 2020 at 3:29 PM Alex Deucher wrote: > > On Tue, May 12, 2020 at 9:17 AM Daniel Vetter wrote: > > > > On Tue, May 12, 2020 at 3:12 PM Alex Deucher wrote: > > > > > > On Tue, May 12, 2020 at 8:58 AM Daniel Vetter wrote: > > > > > > > > On Tue, May 12, 2020 at 08:54:45AM -0400, Alex Deucher wrote: > > > > > On Tue, May 12, 2020 at 5:00 AM Daniel Vetter > > > > > wrote: > > > > > > > > > > > > ... > > > > > > > > > > > > I think it's time to stop this little exercise. > > > > > > > > > > > > The lockdep splat, for the record: > > > > > > > > > > > > [ 132.583381] > > > > > > == > > > > > > [ 132.584091] WARNING: possible circular locking dependency > > > > > > detected > > > > > > [ 132.584775] 5.7.0-rc3+ #346 Tainted: GW > > > > > > [ 132.585461] > > > > > > -- > > > > > > [ 132.586184] kworker/2:3/865 is trying to acquire lock: > > > > > > [ 132.586857] c9677c70 > > > > > > (crtc_ww_class_acquire){+.+.}-{0:0}, at: > > > > > > drm_atomic_helper_suspend+0x38/0x120 [drm_kms_helper] > > > > > > [ 132.587569] > > > > > >but task is already holding lock: > > > > > > [ 132.589044] 82318c80 (dma_fence_map){}-{0:0}, at: > > > > > > drm_sched_job_timedout+0x25/0xf0 [gpu_sched] > > > > > > [ 132.589803] > > > > > >which lock already depends on the new lock. > > > > > > > > > > > > [ 132.592009] > > > > > >the existing dependency chain (in reverse order) is: > > > > > > [ 132.593507] > > > > > >-> #2 (dma_fence_map){}-{0:0}: > > > > > > [ 132.595019]dma_fence_begin_signalling+0x50/0x60 > > > > > > [ 132.595767]drm_atomic_helper_commit+0xa1/0x180 > > > > > > [drm_kms_helper] > > > > > > [ 132.596567]drm_client_modeset_commit_atomic+0x1ea/0x250 > > > > > > [drm] > > > > > > [ 132.597420]drm_client_modeset_commit_locked+0x55/0x190 > > > > > > [drm] > > > > > > [ 132.598178]drm_client_modeset_commit+0x24/0x40 [drm] > > > > > > [ 132.598948] > > > > > > drm_fb_helper_restore_fbdev_mode_unlocked+0x4b/0xa0 [drm_kms_helper] > > > > > > [ 132.599738]drm_fb_helper_set_par+0x30/0x40 > > > > > > [drm_kms_helper] > > > > > > [ 132.600539]fbcon_init+0x2e8/0x660 > > > > > > [ 132.601344]visual_init+0xce/0x130 > > > > > > [ 132.602156]do_bind_con_driver+0x1bc/0x2b0 > > > > > > [ 132.602970]do_take_over_console+0x115/0x180 > > > > > > [ 132.603763]do_fbcon_takeover+0x58/0xb0 > > > > > > [ 132.604564]register_framebuffer+0x1ee/0x300 > > > > > > [ 132.605369] > > > > > > __drm_fb_helper_initial_config_and_unlock+0x36e/0x520 > > > > > > [drm_kms_helper] > > > > > > [ 132.606187]amdgpu_fbdev_init+0xb3/0xf0 [amdgpu] > > > > > > [ 132.607032]amdgpu_device_init.cold+0xe90/0x1677 [amdgpu] > > > > > > [ 132.607862]amdgpu_driver_load_kms+0x5a/0x200 [amdgpu] > > > > > > [ 132.608697]amdgpu_pci_probe+0xf7/0x180 [amdgpu] > > > > > > [ 132.609511]local_pci_probe+0x42/0x80 > > > > > > [ 132.610324]pci_device_probe+0x104/0x1a0 > > > > > > [ 132.611130]really_probe+0x147/0x3c0 > > > > > > [ 132.611939]driver_probe_device+0xb6/0x100 > > > > > > [ 132.612766]device_driver_attach+0x53/0x60 > > > > > > [ 132.613593]__driver_attach+0x8c/0x150 > > > > > > [ 132.614419]bus_for_each_dev+0x7b/0xc0 > > > > > > [ 132.615249]bus_add_driver+0x14c/0x1f0 > > > > > > [ 132.616071]driver_register+0x6c/0xc0 > > > > > > [ 132.616902]do_one_initcall+0x5d/0x2f0 > > > > > > [ 132.617731]do_init_module+0x5c/0x230 > > > > > > [ 132.618560]load_module+0x2981/0x2bc0 > > > > > > [ 132.619391]__do_sys_finit_module+0xaa/0x110 > > > > > > [ 132.620228]do_syscall_64+0x5a/0x250 > > > > > > [ 132.621064]entry_SYSCALL_64_after_hwframe+0x49/0xb3 > > > > > > [ 132.621903] > > > > > >-> #1 (crtc_ww_class_mutex){+.+.}-{3:3}: > > > > > > [ 132.623587]__ww_mutex_lock.constprop.0+0xcc/0x10c0 > > > > > > [ 132.624448]ww_mutex_lock+0x43/0xb0 > > > > > > [ 132.625315]drm_modeset_lock+0x44/0x120 [drm] > > > > > > [ 132.626184]drmm_mode_config_init+0x2db/0x8b0 [drm] > > > > > > [ 132.627098]amdgpu_device_init.cold+0xbd1/0x1677 [amdgpu] > > > > > > [ 132.628007]amdgpu_driver_load_kms+0x5a/0x200 [amdgpu] > > > > > > [ 132.628920]amdgpu_pci_probe+0xf7/0x180 [amdgpu] > > > > > > [ 132.629804]local_pci_probe+0x42/0x80 > > > > > > [ 132.630690]pci_device_probe+0x104/0x1a0 > > > > > > [ 132.631583]really_probe+0x147/0x3c0 > > > > > > [ 132.632479]driver_probe_device+0xb6/0x100 > > > > > > [ 132.633379]device_driver_attach+0x53/0x60 > > > > > > [
Re: [RFC 16/17] drm/amdgpu: gpu recovery does full modesets
On Tue, May 12, 2020 at 08:54:45AM -0400, Alex Deucher wrote: > On Tue, May 12, 2020 at 5:00 AM Daniel Vetter wrote: > > > > ... > > > > I think it's time to stop this little exercise. > > > > The lockdep splat, for the record: > > > > [ 132.583381] == > > [ 132.584091] WARNING: possible circular locking dependency detected > > [ 132.584775] 5.7.0-rc3+ #346 Tainted: GW > > [ 132.585461] -- > > [ 132.586184] kworker/2:3/865 is trying to acquire lock: > > [ 132.586857] c9677c70 (crtc_ww_class_acquire){+.+.}-{0:0}, at: > > drm_atomic_helper_suspend+0x38/0x120 [drm_kms_helper] > > [ 132.587569] > >but task is already holding lock: > > [ 132.589044] 82318c80 (dma_fence_map){}-{0:0}, at: > > drm_sched_job_timedout+0x25/0xf0 [gpu_sched] > > [ 132.589803] > >which lock already depends on the new lock. > > > > [ 132.592009] > >the existing dependency chain (in reverse order) is: > > [ 132.593507] > >-> #2 (dma_fence_map){}-{0:0}: > > [ 132.595019]dma_fence_begin_signalling+0x50/0x60 > > [ 132.595767]drm_atomic_helper_commit+0xa1/0x180 [drm_kms_helper] > > [ 132.596567]drm_client_modeset_commit_atomic+0x1ea/0x250 [drm] > > [ 132.597420]drm_client_modeset_commit_locked+0x55/0x190 [drm] > > [ 132.598178]drm_client_modeset_commit+0x24/0x40 [drm] > > [ 132.598948]drm_fb_helper_restore_fbdev_mode_unlocked+0x4b/0xa0 > > [drm_kms_helper] > > [ 132.599738]drm_fb_helper_set_par+0x30/0x40 [drm_kms_helper] > > [ 132.600539]fbcon_init+0x2e8/0x660 > > [ 132.601344]visual_init+0xce/0x130 > > [ 132.602156]do_bind_con_driver+0x1bc/0x2b0 > > [ 132.602970]do_take_over_console+0x115/0x180 > > [ 132.603763]do_fbcon_takeover+0x58/0xb0 > > [ 132.604564]register_framebuffer+0x1ee/0x300 > > [ 132.605369]__drm_fb_helper_initial_config_and_unlock+0x36e/0x520 > > [drm_kms_helper] > > [ 132.606187]amdgpu_fbdev_init+0xb3/0xf0 [amdgpu] > > [ 132.607032]amdgpu_device_init.cold+0xe90/0x1677 [amdgpu] > > [ 132.607862]amdgpu_driver_load_kms+0x5a/0x200 [amdgpu] > > [ 132.608697]amdgpu_pci_probe+0xf7/0x180 [amdgpu] > > [ 132.609511]local_pci_probe+0x42/0x80 > > [ 132.610324]pci_device_probe+0x104/0x1a0 > > [ 132.611130]really_probe+0x147/0x3c0 > > [ 132.611939]driver_probe_device+0xb6/0x100 > > [ 132.612766]device_driver_attach+0x53/0x60 > > [ 132.613593]__driver_attach+0x8c/0x150 > > [ 132.614419]bus_for_each_dev+0x7b/0xc0 > > [ 132.615249]bus_add_driver+0x14c/0x1f0 > > [ 132.616071]driver_register+0x6c/0xc0 > > [ 132.616902]do_one_initcall+0x5d/0x2f0 > > [ 132.617731]do_init_module+0x5c/0x230 > > [ 132.618560]load_module+0x2981/0x2bc0 > > [ 132.619391]__do_sys_finit_module+0xaa/0x110 > > [ 132.620228]do_syscall_64+0x5a/0x250 > > [ 132.621064]entry_SYSCALL_64_after_hwframe+0x49/0xb3 > > [ 132.621903] > >-> #1 (crtc_ww_class_mutex){+.+.}-{3:3}: > > [ 132.623587]__ww_mutex_lock.constprop.0+0xcc/0x10c0 > > [ 132.624448]ww_mutex_lock+0x43/0xb0 > > [ 132.625315]drm_modeset_lock+0x44/0x120 [drm] > > [ 132.626184]drmm_mode_config_init+0x2db/0x8b0 [drm] > > [ 132.627098]amdgpu_device_init.cold+0xbd1/0x1677 [amdgpu] > > [ 132.628007]amdgpu_driver_load_kms+0x5a/0x200 [amdgpu] > > [ 132.628920]amdgpu_pci_probe+0xf7/0x180 [amdgpu] > > [ 132.629804]local_pci_probe+0x42/0x80 > > [ 132.630690]pci_device_probe+0x104/0x1a0 > > [ 132.631583]really_probe+0x147/0x3c0 > > [ 132.632479]driver_probe_device+0xb6/0x100 > > [ 132.633379]device_driver_attach+0x53/0x60 > > [ 132.634275]__driver_attach+0x8c/0x150 > > [ 132.635170]bus_for_each_dev+0x7b/0xc0 > > [ 132.636069]bus_add_driver+0x14c/0x1f0 > > [ 132.636974]driver_register+0x6c/0xc0 > > [ 132.637870]do_one_initcall+0x5d/0x2f0 > > [ 132.638765]do_init_module+0x5c/0x230 > > [ 132.639654]load_module+0x2981/0x2bc0 > > [ 132.640522]__do_sys_finit_module+0xaa/0x110 > > [ 132.641372]do_syscall_64+0x5a/0x250 > > [ 132.642203]entry_SYSCALL_64_after_hwframe+0x49/0xb3 > > [ 132.643022] > >-> #0 (crtc_ww_class_acquire){+.+.}-{0:0}: > > [ 132.644643]__lock_acquire+0x1241/0x23f0 > > [ 132.645469]lock_acquire+0xad/0x370 > > [ 132.646274]drm_modeset_acquire_init+0xd2/0x100 [drm] > > [ 132.647071]drm_atomic_helper_suspend+0x38/0x120 [drm_kms_helper] > > [ 132.647902]dm_suspend+0x1c/0x60 [amdgpu] > > [ 132.648698]
Re: [RFC 02/17] dma-fence: basic lockdep annotations
On Tue, May 12, 2020 at 09:09:52AM -0300, Jason Gunthorpe wrote: > On Tue, May 12, 2020 at 10:59:29AM +0200, Daniel Vetter wrote: > > diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c > > index 6802125349fb..d5c0fd2efc70 100644 > > +++ b/drivers/dma-buf/dma-fence.c > > @@ -110,6 +110,52 @@ u64 dma_fence_context_alloc(unsigned num) > > } > > EXPORT_SYMBOL(dma_fence_context_alloc); > > > > +#ifdef CONFIG_LOCKDEP > > +struct lockdep_map dma_fence_lockdep_map = { > > + .name = "dma_fence_map" > > +}; > > + > > +bool dma_fence_begin_signalling(void) > > +{ > > Why is this global? I would have expected it to be connected to a > single fence? It's the same rules for all fences, since they can be shared across drivers in various ways. Lockdep usually achieves that with a static variable hidden in the macro, but that doesn't work if you have lots of different ways from different drivers to create a dma_fence. Hence the unique global one that we explicitly allocate. We have similar stuff for the global dma_resv_lock ww_mutex class, just there it's a bit more standardized and hidden behind a neat macro. But really lockdep needs global lockdep_maps or it doesn't work. > It would also be alot nicer if this was some general lockdep feature, > not tied to dmabuf. This exact problem also strikes anyone using > completions, for instance, and the same solution should be > applicable?? There was: https://lwn.net/Articles/709849/ It even got merged, and seems to have worked. Unfortunately (and I'm not entirely clear on the reasons) it was thrown out again, so we can't use it. That means wait_event/wake_up dependencies need to be manually annotated, like e.g. flush_work() already is. flush_work is more or less where I've stolen this idea from, with some adjustements and tricks on top to make it work for dma_fence users. Cheers, Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH -next] drm/mcde: dsi: Fix return value check in dev_err()
Hi all, On Tue, 12 May 2020 at 12:49, Linus Walleij wrote: > > On Tue, Apr 28, 2020 at 4:13 PM Wei Yongjun wrote: > > > In case of error, the function of_drm_find_bridge() returns NULL pointer > > not ERR_PTR(). The IS_ERR() test in the return value check should be > > replaced with NULL test. > > > > Signed-off-by: Wei Yongjun > > Patch applied! Thanks Wei, sorry for the long delay. > It would be nice if of_drm_find_bridge and of_drm_find_panel were consistent - either return NULL or an ERR_PTR. Otherwise the next person using them is likely to get it wrong. -Emil ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 207693] amdgpu: RX 5500 XT boost frequency out of spec
https://bugzilla.kernel.org/show_bug.cgi?id=207693 --- Comment #2 from Jan Ziak (http://atom-symbol.net) (0xe2.0x9a.0...@gmail.com) --- (In reply to Alex Deucher from comment #1) > The vbios defines the clock frequencies and nominal voltages, not the > driver. The voltage is changed dynamically at runtime based on frequency > and power and individual board leakage so you will see slight variations at > runtime depending on the board. particlefire from Vulkan demos (https://github.com/SaschaWillems/Vulkan) is an app with a relatively high power consumption (higher power consumption than Aida64 GPU stability test). On my machine it has performance of about 1000 FPS in a maximized window. I let it run for about 20 minutes, during which I manipulated GPU's fan speed. According to /usr/bin/sensors, the GPU's junction/hotspot critical temperature is 99°C. So I lowered the fan RPM to less than 1000 in order to achieve higher temperatures. Even when the hotspot temperature was 105°C (6°C above critical) and GPU edge temperature was 86°C it had no effect on the FPS of particlefire (still about 1000 FPS). radeontop (https://github.com/clbr/radeontop) was showing 1885MHz all the time during the testing. In summary, I am unable to confirm your claim that the GPU is self-adjusting its voltage or frequency in Linux. If you know an alternative approach (other than the one described above) to verify that the GPU is dynamically changing voltage and frequency in Linux due to temperatures and power consumption, please let me know. -- You are receiving this mail because: You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 1/3] drm/radeon: remove AGP support
On Tue, May 12, 2020 at 4:16 AM Michel Dänzer wrote: > > On 2020-05-11 10:12 p.m., Alex Deucher wrote: > > On Mon, May 11, 2020 at 1:17 PM Christian König > > wrote: > >> > >> AGP is deprecated for 10+ years now and not used any more on modern > >> hardware. > >> > >> Old hardware should continue to work in PCI mode. > > > > Might want to clarify that there is no loss of functionality here. > > Something like: > > > > "There is no loss of functionality here. GPUs will continue to > > function. This just drops the use of the AGP MMU in the chipset in > > favor of the MMU on the device which has proven to be much more > > reliable. Due to its unreliability, AGP support has been disabled on > > PowerPC for years already so there is no change on PowerPC." > > There's a difference between something being disabled by default or not > being available at all. We may decide it's worth it anyway, but let's do > it based on facts. > I didn't mean to imply that AGP GART support was already removed. But for the vast majority of users the end result is the same. If you knew enough re-enable AGP GART, you probably wouldn't have been as confused about what this patch set does either. To reiterate, this patch set does not remove support for AGP cards, it only removes the support for AGP GART. The cards will still be functional using the device GART. There may be performance tradeoffs there in some cases. Alex ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH][next] drm/amdgpu: remove redundant assignment to variable ret
From: Colin Ian King The variable ret is being initializeed with a value that is never read and it is being updated later with a new value. The initialization is redundant and can be removed. Addresses-Coverity: ("Unused value") Signed-off-by: Colin Ian King --- drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c index 90610b4f2c75..e9e59bc68c9f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c @@ -441,7 +441,7 @@ int amdgpu_xgmi_set_pstate(struct amdgpu_device *adev, int pstate) int amdgpu_xgmi_update_topology(struct amdgpu_hive_info *hive, struct amdgpu_device *adev) { - int ret = -EINVAL; + int ret; /* Each psp need to set the latest topology */ ret = psp_xgmi_set_topology_info(>psp, -- 2.25.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC 16/17] drm/amdgpu: gpu recovery does full modesets
On Tue, May 12, 2020 at 5:00 AM Daniel Vetter wrote: > > ... > > I think it's time to stop this little exercise. > > The lockdep splat, for the record: > > [ 132.583381] == > [ 132.584091] WARNING: possible circular locking dependency detected > [ 132.584775] 5.7.0-rc3+ #346 Tainted: GW > [ 132.585461] -- > [ 132.586184] kworker/2:3/865 is trying to acquire lock: > [ 132.586857] c9677c70 (crtc_ww_class_acquire){+.+.}-{0:0}, at: > drm_atomic_helper_suspend+0x38/0x120 [drm_kms_helper] > [ 132.587569] >but task is already holding lock: > [ 132.589044] 82318c80 (dma_fence_map){}-{0:0}, at: > drm_sched_job_timedout+0x25/0xf0 [gpu_sched] > [ 132.589803] >which lock already depends on the new lock. > > [ 132.592009] >the existing dependency chain (in reverse order) is: > [ 132.593507] >-> #2 (dma_fence_map){}-{0:0}: > [ 132.595019]dma_fence_begin_signalling+0x50/0x60 > [ 132.595767]drm_atomic_helper_commit+0xa1/0x180 [drm_kms_helper] > [ 132.596567]drm_client_modeset_commit_atomic+0x1ea/0x250 [drm] > [ 132.597420]drm_client_modeset_commit_locked+0x55/0x190 [drm] > [ 132.598178]drm_client_modeset_commit+0x24/0x40 [drm] > [ 132.598948]drm_fb_helper_restore_fbdev_mode_unlocked+0x4b/0xa0 > [drm_kms_helper] > [ 132.599738]drm_fb_helper_set_par+0x30/0x40 [drm_kms_helper] > [ 132.600539]fbcon_init+0x2e8/0x660 > [ 132.601344]visual_init+0xce/0x130 > [ 132.602156]do_bind_con_driver+0x1bc/0x2b0 > [ 132.602970]do_take_over_console+0x115/0x180 > [ 132.603763]do_fbcon_takeover+0x58/0xb0 > [ 132.604564]register_framebuffer+0x1ee/0x300 > [ 132.605369]__drm_fb_helper_initial_config_and_unlock+0x36e/0x520 > [drm_kms_helper] > [ 132.606187]amdgpu_fbdev_init+0xb3/0xf0 [amdgpu] > [ 132.607032]amdgpu_device_init.cold+0xe90/0x1677 [amdgpu] > [ 132.607862]amdgpu_driver_load_kms+0x5a/0x200 [amdgpu] > [ 132.608697]amdgpu_pci_probe+0xf7/0x180 [amdgpu] > [ 132.609511]local_pci_probe+0x42/0x80 > [ 132.610324]pci_device_probe+0x104/0x1a0 > [ 132.611130]really_probe+0x147/0x3c0 > [ 132.611939]driver_probe_device+0xb6/0x100 > [ 132.612766]device_driver_attach+0x53/0x60 > [ 132.613593]__driver_attach+0x8c/0x150 > [ 132.614419]bus_for_each_dev+0x7b/0xc0 > [ 132.615249]bus_add_driver+0x14c/0x1f0 > [ 132.616071]driver_register+0x6c/0xc0 > [ 132.616902]do_one_initcall+0x5d/0x2f0 > [ 132.617731]do_init_module+0x5c/0x230 > [ 132.618560]load_module+0x2981/0x2bc0 > [ 132.619391]__do_sys_finit_module+0xaa/0x110 > [ 132.620228]do_syscall_64+0x5a/0x250 > [ 132.621064]entry_SYSCALL_64_after_hwframe+0x49/0xb3 > [ 132.621903] >-> #1 (crtc_ww_class_mutex){+.+.}-{3:3}: > [ 132.623587]__ww_mutex_lock.constprop.0+0xcc/0x10c0 > [ 132.624448]ww_mutex_lock+0x43/0xb0 > [ 132.625315]drm_modeset_lock+0x44/0x120 [drm] > [ 132.626184]drmm_mode_config_init+0x2db/0x8b0 [drm] > [ 132.627098]amdgpu_device_init.cold+0xbd1/0x1677 [amdgpu] > [ 132.628007]amdgpu_driver_load_kms+0x5a/0x200 [amdgpu] > [ 132.628920]amdgpu_pci_probe+0xf7/0x180 [amdgpu] > [ 132.629804]local_pci_probe+0x42/0x80 > [ 132.630690]pci_device_probe+0x104/0x1a0 > [ 132.631583]really_probe+0x147/0x3c0 > [ 132.632479]driver_probe_device+0xb6/0x100 > [ 132.633379]device_driver_attach+0x53/0x60 > [ 132.634275]__driver_attach+0x8c/0x150 > [ 132.635170]bus_for_each_dev+0x7b/0xc0 > [ 132.636069]bus_add_driver+0x14c/0x1f0 > [ 132.636974]driver_register+0x6c/0xc0 > [ 132.637870]do_one_initcall+0x5d/0x2f0 > [ 132.638765]do_init_module+0x5c/0x230 > [ 132.639654]load_module+0x2981/0x2bc0 > [ 132.640522]__do_sys_finit_module+0xaa/0x110 > [ 132.641372]do_syscall_64+0x5a/0x250 > [ 132.642203]entry_SYSCALL_64_after_hwframe+0x49/0xb3 > [ 132.643022] >-> #0 (crtc_ww_class_acquire){+.+.}-{0:0}: > [ 132.644643]__lock_acquire+0x1241/0x23f0 > [ 132.645469]lock_acquire+0xad/0x370 > [ 132.646274]drm_modeset_acquire_init+0xd2/0x100 [drm] > [ 132.647071]drm_atomic_helper_suspend+0x38/0x120 [drm_kms_helper] > [ 132.647902]dm_suspend+0x1c/0x60 [amdgpu] > [ 132.648698]amdgpu_device_ip_suspend_phase1+0x83/0xe0 [amdgpu] > [ 132.649498]amdgpu_device_ip_suspend+0x1c/0x60 [amdgpu] > [ 132.650300]amdgpu_device_gpu_recover.cold+0x4e6/0xe64 [amdgpu] > [ 132.651084]amdgpu_job_timedout+0xfb/0x150 [amdgpu] > [ 132.651825]
Re: [RFC 16/17] drm/amdgpu: gpu recovery does full modesets
On Tue, May 12, 2020 at 8:58 AM Daniel Vetter wrote: > > On Tue, May 12, 2020 at 08:54:45AM -0400, Alex Deucher wrote: > > On Tue, May 12, 2020 at 5:00 AM Daniel Vetter > > wrote: > > > > > > ... > > > > > > I think it's time to stop this little exercise. > > > > > > The lockdep splat, for the record: > > > > > > [ 132.583381] == > > > [ 132.584091] WARNING: possible circular locking dependency detected > > > [ 132.584775] 5.7.0-rc3+ #346 Tainted: GW > > > [ 132.585461] -- > > > [ 132.586184] kworker/2:3/865 is trying to acquire lock: > > > [ 132.586857] c9677c70 (crtc_ww_class_acquire){+.+.}-{0:0}, at: > > > drm_atomic_helper_suspend+0x38/0x120 [drm_kms_helper] > > > [ 132.587569] > > >but task is already holding lock: > > > [ 132.589044] 82318c80 (dma_fence_map){}-{0:0}, at: > > > drm_sched_job_timedout+0x25/0xf0 [gpu_sched] > > > [ 132.589803] > > >which lock already depends on the new lock. > > > > > > [ 132.592009] > > >the existing dependency chain (in reverse order) is: > > > [ 132.593507] > > >-> #2 (dma_fence_map){}-{0:0}: > > > [ 132.595019]dma_fence_begin_signalling+0x50/0x60 > > > [ 132.595767]drm_atomic_helper_commit+0xa1/0x180 [drm_kms_helper] > > > [ 132.596567]drm_client_modeset_commit_atomic+0x1ea/0x250 [drm] > > > [ 132.597420]drm_client_modeset_commit_locked+0x55/0x190 [drm] > > > [ 132.598178]drm_client_modeset_commit+0x24/0x40 [drm] > > > [ 132.598948]drm_fb_helper_restore_fbdev_mode_unlocked+0x4b/0xa0 > > > [drm_kms_helper] > > > [ 132.599738]drm_fb_helper_set_par+0x30/0x40 [drm_kms_helper] > > > [ 132.600539]fbcon_init+0x2e8/0x660 > > > [ 132.601344]visual_init+0xce/0x130 > > > [ 132.602156]do_bind_con_driver+0x1bc/0x2b0 > > > [ 132.602970]do_take_over_console+0x115/0x180 > > > [ 132.603763]do_fbcon_takeover+0x58/0xb0 > > > [ 132.604564]register_framebuffer+0x1ee/0x300 > > > [ 132.605369] > > > __drm_fb_helper_initial_config_and_unlock+0x36e/0x520 [drm_kms_helper] > > > [ 132.606187]amdgpu_fbdev_init+0xb3/0xf0 [amdgpu] > > > [ 132.607032]amdgpu_device_init.cold+0xe90/0x1677 [amdgpu] > > > [ 132.607862]amdgpu_driver_load_kms+0x5a/0x200 [amdgpu] > > > [ 132.608697]amdgpu_pci_probe+0xf7/0x180 [amdgpu] > > > [ 132.609511]local_pci_probe+0x42/0x80 > > > [ 132.610324]pci_device_probe+0x104/0x1a0 > > > [ 132.611130]really_probe+0x147/0x3c0 > > > [ 132.611939]driver_probe_device+0xb6/0x100 > > > [ 132.612766]device_driver_attach+0x53/0x60 > > > [ 132.613593]__driver_attach+0x8c/0x150 > > > [ 132.614419]bus_for_each_dev+0x7b/0xc0 > > > [ 132.615249]bus_add_driver+0x14c/0x1f0 > > > [ 132.616071]driver_register+0x6c/0xc0 > > > [ 132.616902]do_one_initcall+0x5d/0x2f0 > > > [ 132.617731]do_init_module+0x5c/0x230 > > > [ 132.618560]load_module+0x2981/0x2bc0 > > > [ 132.619391]__do_sys_finit_module+0xaa/0x110 > > > [ 132.620228]do_syscall_64+0x5a/0x250 > > > [ 132.621064]entry_SYSCALL_64_after_hwframe+0x49/0xb3 > > > [ 132.621903] > > >-> #1 (crtc_ww_class_mutex){+.+.}-{3:3}: > > > [ 132.623587]__ww_mutex_lock.constprop.0+0xcc/0x10c0 > > > [ 132.624448]ww_mutex_lock+0x43/0xb0 > > > [ 132.625315]drm_modeset_lock+0x44/0x120 [drm] > > > [ 132.626184]drmm_mode_config_init+0x2db/0x8b0 [drm] > > > [ 132.627098]amdgpu_device_init.cold+0xbd1/0x1677 [amdgpu] > > > [ 132.628007]amdgpu_driver_load_kms+0x5a/0x200 [amdgpu] > > > [ 132.628920]amdgpu_pci_probe+0xf7/0x180 [amdgpu] > > > [ 132.629804]local_pci_probe+0x42/0x80 > > > [ 132.630690]pci_device_probe+0x104/0x1a0 > > > [ 132.631583]really_probe+0x147/0x3c0 > > > [ 132.632479]driver_probe_device+0xb6/0x100 > > > [ 132.633379]device_driver_attach+0x53/0x60 > > > [ 132.634275]__driver_attach+0x8c/0x150 > > > [ 132.635170]bus_for_each_dev+0x7b/0xc0 > > > [ 132.636069]bus_add_driver+0x14c/0x1f0 > > > [ 132.636974]driver_register+0x6c/0xc0 > > > [ 132.637870]do_one_initcall+0x5d/0x2f0 > > > [ 132.638765]do_init_module+0x5c/0x230 > > > [ 132.639654]load_module+0x2981/0x2bc0 > > > [ 132.640522]__do_sys_finit_module+0xaa/0x110 > > > [ 132.641372]do_syscall_64+0x5a/0x250 > > > [ 132.642203]entry_SYSCALL_64_after_hwframe+0x49/0xb3 > > > [ 132.643022] > > >-> #0 (crtc_ww_class_acquire){+.+.}-{0:0}: > > > [ 132.644643]__lock_acquire+0x1241/0x23f0 > > > [ 132.645469]lock_acquire+0xad/0x370 > > > [ 132.646274]
Re: [RFC 16/17] drm/amdgpu: gpu recovery does full modesets
On Tue, May 12, 2020 at 3:12 PM Alex Deucher wrote: > > On Tue, May 12, 2020 at 8:58 AM Daniel Vetter wrote: > > > > On Tue, May 12, 2020 at 08:54:45AM -0400, Alex Deucher wrote: > > > On Tue, May 12, 2020 at 5:00 AM Daniel Vetter > > > wrote: > > > > > > > > ... > > > > > > > > I think it's time to stop this little exercise. > > > > > > > > The lockdep splat, for the record: > > > > > > > > [ 132.583381] == > > > > [ 132.584091] WARNING: possible circular locking dependency detected > > > > [ 132.584775] 5.7.0-rc3+ #346 Tainted: GW > > > > [ 132.585461] -- > > > > [ 132.586184] kworker/2:3/865 is trying to acquire lock: > > > > [ 132.586857] c9677c70 (crtc_ww_class_acquire){+.+.}-{0:0}, > > > > at: drm_atomic_helper_suspend+0x38/0x120 [drm_kms_helper] > > > > [ 132.587569] > > > >but task is already holding lock: > > > > [ 132.589044] 82318c80 (dma_fence_map){}-{0:0}, at: > > > > drm_sched_job_timedout+0x25/0xf0 [gpu_sched] > > > > [ 132.589803] > > > >which lock already depends on the new lock. > > > > > > > > [ 132.592009] > > > >the existing dependency chain (in reverse order) is: > > > > [ 132.593507] > > > >-> #2 (dma_fence_map){}-{0:0}: > > > > [ 132.595019]dma_fence_begin_signalling+0x50/0x60 > > > > [ 132.595767]drm_atomic_helper_commit+0xa1/0x180 > > > > [drm_kms_helper] > > > > [ 132.596567]drm_client_modeset_commit_atomic+0x1ea/0x250 [drm] > > > > [ 132.597420]drm_client_modeset_commit_locked+0x55/0x190 [drm] > > > > [ 132.598178]drm_client_modeset_commit+0x24/0x40 [drm] > > > > [ 132.598948] > > > > drm_fb_helper_restore_fbdev_mode_unlocked+0x4b/0xa0 [drm_kms_helper] > > > > [ 132.599738]drm_fb_helper_set_par+0x30/0x40 [drm_kms_helper] > > > > [ 132.600539]fbcon_init+0x2e8/0x660 > > > > [ 132.601344]visual_init+0xce/0x130 > > > > [ 132.602156]do_bind_con_driver+0x1bc/0x2b0 > > > > [ 132.602970]do_take_over_console+0x115/0x180 > > > > [ 132.603763]do_fbcon_takeover+0x58/0xb0 > > > > [ 132.604564]register_framebuffer+0x1ee/0x300 > > > > [ 132.605369] > > > > __drm_fb_helper_initial_config_and_unlock+0x36e/0x520 [drm_kms_helper] > > > > [ 132.606187]amdgpu_fbdev_init+0xb3/0xf0 [amdgpu] > > > > [ 132.607032]amdgpu_device_init.cold+0xe90/0x1677 [amdgpu] > > > > [ 132.607862]amdgpu_driver_load_kms+0x5a/0x200 [amdgpu] > > > > [ 132.608697]amdgpu_pci_probe+0xf7/0x180 [amdgpu] > > > > [ 132.609511]local_pci_probe+0x42/0x80 > > > > [ 132.610324]pci_device_probe+0x104/0x1a0 > > > > [ 132.611130]really_probe+0x147/0x3c0 > > > > [ 132.611939]driver_probe_device+0xb6/0x100 > > > > [ 132.612766]device_driver_attach+0x53/0x60 > > > > [ 132.613593]__driver_attach+0x8c/0x150 > > > > [ 132.614419]bus_for_each_dev+0x7b/0xc0 > > > > [ 132.615249]bus_add_driver+0x14c/0x1f0 > > > > [ 132.616071]driver_register+0x6c/0xc0 > > > > [ 132.616902]do_one_initcall+0x5d/0x2f0 > > > > [ 132.617731]do_init_module+0x5c/0x230 > > > > [ 132.618560]load_module+0x2981/0x2bc0 > > > > [ 132.619391]__do_sys_finit_module+0xaa/0x110 > > > > [ 132.620228]do_syscall_64+0x5a/0x250 > > > > [ 132.621064]entry_SYSCALL_64_after_hwframe+0x49/0xb3 > > > > [ 132.621903] > > > >-> #1 (crtc_ww_class_mutex){+.+.}-{3:3}: > > > > [ 132.623587]__ww_mutex_lock.constprop.0+0xcc/0x10c0 > > > > [ 132.624448]ww_mutex_lock+0x43/0xb0 > > > > [ 132.625315]drm_modeset_lock+0x44/0x120 [drm] > > > > [ 132.626184]drmm_mode_config_init+0x2db/0x8b0 [drm] > > > > [ 132.627098]amdgpu_device_init.cold+0xbd1/0x1677 [amdgpu] > > > > [ 132.628007]amdgpu_driver_load_kms+0x5a/0x200 [amdgpu] > > > > [ 132.628920]amdgpu_pci_probe+0xf7/0x180 [amdgpu] > > > > [ 132.629804]local_pci_probe+0x42/0x80 > > > > [ 132.630690]pci_device_probe+0x104/0x1a0 > > > > [ 132.631583]really_probe+0x147/0x3c0 > > > > [ 132.632479]driver_probe_device+0xb6/0x100 > > > > [ 132.633379]device_driver_attach+0x53/0x60 > > > > [ 132.634275]__driver_attach+0x8c/0x150 > > > > [ 132.635170]bus_for_each_dev+0x7b/0xc0 > > > > [ 132.636069]bus_add_driver+0x14c/0x1f0 > > > > [ 132.636974]driver_register+0x6c/0xc0 > > > > [ 132.637870]do_one_initcall+0x5d/0x2f0 > > > > [ 132.638765]do_init_module+0x5c/0x230 > > > > [ 132.639654]load_module+0x2981/0x2bc0 > > > > [ 132.640522]__do_sys_finit_module+0xaa/0x110 > > > > [ 132.641372]do_syscall_64+0x5a/0x250 > > > > [ 132.642203]
Re: [RFC v2] drm/connector: Add support for privacy-screen properties (v2)
On Tue, 12 May 2020 10:02:12 +0200 Hans de Goede wrote: > Hi, > > On 5/12/20 9:49 AM, Pekka Paalanen wrote: > > On Mon, 11 May 2020 19:47:24 +0200 > > Hans de Goede wrote: > > > >> From: Rajat Jain > >> > >> Add support for generic electronic privacy screen properties, that > >> can be added by systems that have an integrated EPS. > >> > >> Changes in v2 (Hans de Goede) > >> - Create 2 properties, "privacy-screen sw-state" and > >>"privacy-screen hw-state", to deal with devices where the OS might be > >>locked out of making state changes > >> - Write kerneldoc explaining how the 2 properties work together, what > >>happens when changes to the state are made outside of the DRM code's > >>control, etc. > >> > >> Signed-off-by: Rajat Jain > >> Co-authored-by: Hans de Goede > >> Signed-off-by: Hans de Goede > >> --- > >> Documentation/gpu/drm-kms.rst | 2 + > >> drivers/gpu/drm/drm_atomic_uapi.c | 6 ++ > >> drivers/gpu/drm/drm_connector.c | 100 ++ > >> include/drm/drm_connector.h | 50 +++ > >> 4 files changed, 158 insertions(+) > > > > ... > > > >> diff --git a/drivers/gpu/drm/drm_connector.c > >> b/drivers/gpu/drm/drm_connector.c > >> index 644f0ad10671..01360edc2376 100644 > >> --- a/drivers/gpu/drm/drm_connector.c > >> +++ b/drivers/gpu/drm/drm_connector.c > >> @@ -1186,6 +1186,45 @@ static const struct drm_prop_enum_list > >> dp_colorspaces[] = { > >>* can also expose this property to external outputs, in which > >> case they > >>* must support "None", which should be the default (since > >> external screens > >>* have a built-in scaler). > >> + * > >> + * privacy-screen sw-state, privacy-screen hw-state: > >> + *These 2 optional properties can be used to query the state of > >> the > >> + *electronic privacy screen that is available on some displays; > >> and in > >> + *some cases also control the state. If a driver implements these > >> + *properties then both properties must be present. > >> + * > >> + *"privacy-screen hw-state" is read-only and reflects the actual > >> state > >> + *of the privacy-screen, possible values: "Enabled", "Disabled, > >> + *"Enabled, locked", "Disabled, locked". The locked states > >> indicate > >> + *that the state cannot be changed through the DRM API. E.g. there > >> + *might be devices where the firmware-setup options, or a hardware > >> + *slider-switch, offer always on / off modes. > >> + * > >> + *"privacy-screen sw-state" can be set to change the > >> privacy-screen state > >> + *when not locked. In this case the driver must update the > >> hw-state > >> + *property to reflect the new state on completion of the commit > >> of the > >> + *sw-state property. Setting the sw-state property when the > >> hw-state is > >> + *locked must be interpreted by the driver as a request to change > >> the > >> + *state to the set state when the hw-state becomes unlocked. E.g. > >> if > >> + *"privacy-screen hw-state" is "Enabled, locked" and the sw-state > >> + *gets set to "Disabled" followed by the user unlocking the state > >> by > >> + *changing the slider-switch position, then the driver must set > >> the > >> + *state to "Disabled" upon receiving the unlock event. > >> + * > >> + *In some cases the privacy-screen state might change outside of > >> control > >> + *of the DRM code. E.g. there might be a firmware handled hotkey > >> which > >> + *toggles the state, or the state might be changed through > >> another > > > > Hi, > > > > in the above three lines, I'd use the term "hardware state" instead of > > just "state" to be explicit. Or should it be "physical state" since > > "hardware state" might be confused with "hw-state" property state? > > Maybe "actual state"? That is what is used a few lines higher: > > '"privacy-screen hw-state" is read-only and reflects the actual state' > > And you use it yourself to describe what we want below: > > > I don't mind as long as it's unambiguous and distinguishes explicitly > > between actual and the two property states. > > So since you and I both naturally described it as "actual state" without > thinking too much what we where writing at the time (I guess that applies > to your use too), "actual state" seems a good fit ? Sure! Thanks, pq pgpua1KDkCdrY.pgp Description: OpenPGP digital signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v4 00/38] DRM: fix struct sg_table nents vs. orig_nents misuse
Dear All, During the Exynos DRM GEM rework and fixing the issues in the. drm_prime_sg_to_page_addr_arrays() function [1] I've noticed that most drivers in DRM framework incorrectly use nents and orig_nents entries of the struct sg_table. In case of the most DMA-mapping implementations exchanging those two entries or using nents for all loops on the scatterlist is harmless, because they both have the same value. There exists however a DMA-mapping implementations, for which such incorrect usage breaks things. The nents returned by dma_map_sg() might be lower than the nents passed as its parameter and this is perfectly fine. DMA framework or IOMMU is allowed to join consecutive chunks while mapping if such operation is supported by the underlying HW (bus, bridge, IOMMU, etc). Example of the case where dma_map_sg() might return 1 'DMA' chunk for the 4 'physical' pages is described here [2] The DMA-mapping framework documentation [3] states that dma_map_sg() returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of entries passed to dma_map_sg. The common pattern in DRM drivers were to assign the dma_map_sg() return value to sg_table->nents and use that value for the subsequent calls to dma_sync_sg_* or dma_unmap_sg functions. Also the code iterated over nents times to access the pages stored in the processed scatterlist, while it should use orig_nents as the numer of the page entries. I've tried to identify all such incorrect usage of sg_table->nents and this is a result of my research. It looks that the incorrect pattern has been copied over the many drivers mainly in the DRM subsystem. Too bad in most cases it even worked correctly if the system used a simple, linear DMA-mapping implementation, for which swapping nents and orig_nents doesn't make any difference. To avoid similar issues in the future, I've introduced a common wrappers for DMA-mapping calls, which operate directly on the sg_table objects. I've also added wrappers for iterating over the scatterlists stored in the sg_table objects and applied them where possible. This, together with some common DRM prime helpers, allowed me to almost get rid of all nents/orig_nents usage in the drivers. I hope that such change makes the code robust, easier to follow and copy/paste safe. The biggest TODO is DRM/i915 driver and I don't feel brave enough to fix it fully. The driver creatively uses sg_table->orig_nents to store the size of the allocate scatterlist and ignores the number of the entries returned by dma_map_sg function. In this patchset I only fixed the sg_table objects exported by dmabuf related functions. I hope that I didn't break anything there. Patches are based on top of Linux next-20200511. Best regards, Marek Szyprowski References: [1] https://lkml.org/lkml/2020/3/27/555. [2] https://lkml.org/lkml/2020/3/29/65 [3] Documentation/DMA-API-HOWTO.txt Changelog: v4: - added for_each_sgtable_* wrappers and applied where possible - added drm_prime_get_contiguous_size() and applied where possible - applied drm_prime_sg_to_page_addr_arrays() where possible to remove page extraction from sg_table objects - added documentation for the introduced wrappers - improved patches description a bit v3: https://lore.kernel.org/dri-devel/20200505083926.28503-1-m.szyprow...@samsung.com/ - introduce dma_*_sgtable_* wrappers and use them in all patches v2: https://lore.kernel.org/linux-iommu/c01c9766-9778-fd1f-f36e-2dc7bd376...@arm.com/T/ - dropped most of the changes to drm/i915 - added fixes for rcar-du, xen, media and ion - fixed a few issues pointed by kbuild test robot - added wide cc: list for each patch v1: https://lore.kernel.org/linux-iommu/c01c9766-9778-fd1f-f36e-2dc7bd376...@arm.com/T/ - initial version Patch summary: Marek Szyprowski (38): dma-mapping: add generic helpers for mapping sgtable objects scatterlist: add generic wrappers for iterating over sgtable objects iommu: add generic helper for mapping sgtable objects drm: prime: add common helper to check scatterlist contiguity drm: prime: use sgtable iterators in drm_prime_sg_to_page_addr_arrays() drm: core: fix common struct sg_table related issues drm: amdgpu: fix common struct sg_table related issues drm: armada: fix common struct sg_table related issues drm: etnaviv: fix common struct sg_table related issues drm: exynos: use common helper for a scatterlist contiguity check drm: exynos: fix common struct sg_table related issues drm: i915: fix common struct sg_table related issues drm: lima: fix common struct sg_table related issues drm: mediatek: use common helper for a scatterlist contiguity check drm: mediatek: use common helper for extracting pages array drm: msm: fix common struct sg_table related issues drm: omapdrm: use common helper for extracting pages array drm: omapdrm: fix common struct sg_table
Re: [PATCH v2] dma-buf: fix use-after-free in dmabuffs_dname
On Fri, May 08, 2020 at 12:11:03PM +0530, Charan Teja Reddy wrote: > The following race occurs while accessing the dmabuf object exported as > file: > P1P2 > dma_buf_release() dmabuffs_dname() > [say lsof reading /proc//fd/] > > read dmabuf stored in dentry->d_fsdata > Free the dmabuf object > Start accessing the dmabuf structure > > In the above description, the dmabuf object freed in P1 is being > accessed from P2 which is resulting into the use-after-free. Below is > the dump stack reported. > > We are reading the dmabuf object stored in the dentry->d_fsdata but > there is no binding between the dentry and the dmabuf which means that > the dmabuf can be freed while it is being read from ->d_fsdata and > inuse. Reviews on the patch V1 says that protecting the dmabuf inuse > with an extra refcount is not a viable solution as the exported dmabuf > is already under file's refcount and keeping the multiple refcounts on > the same object coordinated is not possible. > > As we are reading the dmabuf in ->d_fsdata just to get the user passed > name, we can directly store the name in d_fsdata thus can avoid the > reading of dmabuf altogether. > > Call Trace: > kasan_report+0x12/0x20 > __asan_report_load8_noabort+0x14/0x20 > dmabuffs_dname+0x4f4/0x560 > tomoyo_realpath_from_path+0x165/0x660 > tomoyo_get_realpath > tomoyo_check_open_permission+0x2a3/0x3e0 > tomoyo_file_open > tomoyo_file_open+0xa9/0xd0 > security_file_open+0x71/0x300 > do_dentry_open+0x37a/0x1380 > vfs_open+0xa0/0xd0 > path_openat+0x12ee/0x3490 > do_filp_open+0x192/0x260 > do_sys_openat2+0x5eb/0x7e0 > do_sys_open+0xf2/0x180 > > Fixes: bb2bb9030425 ("dma-buf: add DMA_BUF_SET_NAME ioctls") > Reported-by: syzbot+3643a18836bce555b...@syzkaller.appspotmail.com > Cc: [5.3+] > Signed-off-by: Charan Teja Reddy > --- > > Changes in v2: > > - Pass the user passed name in ->d_fsdata instead of dmabuf > - Improve the commit message > > Changes in v1: (https://patchwork.kernel.org/patch/11514063/) > > drivers/dma-buf/dma-buf.c | 17 ++--- > 1 file changed, 10 insertions(+), 7 deletions(-) > > diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c > index 01ce125..0071f7d 100644 > --- a/drivers/dma-buf/dma-buf.c > +++ b/drivers/dma-buf/dma-buf.c > @@ -25,6 +25,7 @@ > #include > #include > #include > +#include > > #include > #include > @@ -40,15 +41,13 @@ struct dma_buf_list { > > static char *dmabuffs_dname(struct dentry *dentry, char *buffer, int buflen) > { > - struct dma_buf *dmabuf; > char name[DMA_BUF_NAME_LEN]; > size_t ret = 0; > > - dmabuf = dentry->d_fsdata; > - dma_resv_lock(dmabuf->resv, NULL); > - if (dmabuf->name) > - ret = strlcpy(name, dmabuf->name, DMA_BUF_NAME_LEN); > - dma_resv_unlock(dmabuf->resv); > + spin_lock(>d_lock); Are you sure this lock always protects d_fsdata? > + if (dentry->d_fsdata) > + ret = strlcpy(name, dentry->d_fsdata, DMA_BUF_NAME_LEN); > + spin_unlock(>d_lock); > > return dynamic_dname(dentry, buffer, buflen, "/%s:%s", >dentry->d_name.name, ret > 0 ? name : ""); If the above check fails the name will be what? How could d_name.name be valid but d_fsdata not be valid? > @@ -80,12 +79,16 @@ static int dma_buf_fs_init_context(struct fs_context *fc) > static int dma_buf_release(struct inode *inode, struct file *file) > { > struct dma_buf *dmabuf; > + struct dentry *dentry = file->f_path.dentry; > > if (!is_dma_buf_file(file)) > return -EINVAL; > > dmabuf = file->private_data; > > + spin_lock(>d_lock); > + dentry->d_fsdata = NULL; > + spin_unlock(>d_lock); > BUG_ON(dmabuf->vmapping_counter); > > /* > @@ -343,6 +346,7 @@ static long dma_buf_set_name(struct dma_buf *dmabuf, > const char __user *buf) > } > kfree(dmabuf->name); > dmabuf->name = name; > + dmabuf->file->f_path.dentry->d_fsdata = name; You are just changing the use of d_fsdata from being a pointer to the dmabuf to being a pointer to the name string? What's to keep that name string around and not have the same reference counting issues that the dmabuf structure itself has? Who frees that string memory? thanks, greg k-h ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC 02/17] dma-fence: basic lockdep annotations
On Tue, May 12, 2020 at 10:04:22AM +0100, Chris Wilson wrote: > Quoting Daniel Vetter (2020-05-12 09:59:29) > > Design is similar to the lockdep annotations for workers, but with > > some twists: > > > > - We use a read-lock for the execution/worker/completion side, so that > > this explicit annotation can be more liberally sprinkled around. > > With read locks lockdep isn't going to complain if the read-side > > isn't nested the same way under all circumstances, so ABBA deadlocks > > are ok. Which they are, since this is an annotation only. > > > > - We're using non-recursive lockdep read lock mode, since in recursive > > read lock mode lockdep does not catch read side hazards. And we > > _very_ much want read side hazards to be caught. For full details of > > this limitation see > > > > commit e91498589746065e3ae95d9a00b068e525eec34f > > Author: Peter Zijlstra > > Date: Wed Aug 23 13:13:11 2017 +0200 > > > > locking/lockdep/selftests: Add mixed read-write ABBA tests > > > > - To allow nesting of the read-side explicit annotations we explicitly > > keep track of the nesting. lock_is_held() allows us to do that. > > > > - The wait-side annotation is a write lock, and entirely done within > > dma_fence_wait() for everyone by default. > > > > - To be able to freely annotate helper functions I want to make it ok > > to call dma_fence_begin/end_signalling from soft/hardirq context. > > First attempt was using the hardirq locking context for the write > > side in lockdep, but this forces all normal spinlocks nested within > > dma_fence_begin/end_signalling to be spinlocks. That bollocks. > > > > The approach now is to simple check in_atomic(), and for these cases > > entirely rely on the might_sleep() check in dma_fence_wait(). That > > will catch any wrong nesting against spinlocks from soft/hardirq > > contexts. > > > > The idea here is that every code path that's critical for eventually > > signalling a dma_fence should be annotated with > > dma_fence_begin/end_signalling. The annotation ideally starts right > > after a dma_fence is published (added to a dma_resv, exposed as a > > sync_file fd, attached to a drm_syncobj fd, or anything else that > > makes the dma_fence visible to other kernel threads), up to and > > including the dma_fence_wait(). Examples are irq handlers, the > > scheduler rt threads, the tail of execbuf (after the corresponding > > fences are visible), any workers that end up signalling dma_fences and > > really anything else. Not annotated should be code paths that only > > complete fences opportunistically as the gpu progresses, like e.g. > > shrinker/eviction code. > > > > The main class of deadlocks this is supposed to catch are: > > > > Thread A: > > > > mutex_lock(A); > > mutex_unlock(A); > > > > dma_fence_signal(); > > > > Thread B: > > > > mutex_lock(A); > > dma_fence_wait(); > > mutex_unlock(A); > > > > Thread B is blocked on A signalling the fence, but A never gets around > > to that because it cannot acquire the lock A. > > > > Note that dma_fence_wait() is allowed to be nested within > > dma_fence_begin/end_signalling sections. To allow this to happen the > > read lock needs to be upgraded to a write lock, which means that any > > other lock is acquired between the dma_fence_begin_signalling() call and > > the call to dma_fence_wait(), and still held, this will result in an > > immediate lockdep complaint. The only other option would be to not > > annotate such calls, defeating the point. Therefore these annotations > > cannot be sprinkled over the code entirely mindless to avoid false > > positives. > > > > v2: handle soft/hardirq ctx better against write side and dont forget > > EXPORT_SYMBOL, drivers can't use this otherwise. > > > > Cc: linux-me...@vger.kernel.org > > Cc: linaro-mm-...@lists.linaro.org > > Cc: linux-r...@vger.kernel.org > > Cc: amd-...@lists.freedesktop.org > > Cc: intel-...@lists.freedesktop.org > > Cc: Chris Wilson > > Cc: Maarten Lankhorst > > Cc: Christian König > > Signed-off-by: Daniel Vetter > > --- > > drivers/dma-buf/dma-fence.c | 53 + > > include/linux/dma-fence.h | 12 + > > 2 files changed, 65 insertions(+) > > > > diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c > > index 6802125349fb..d5c0fd2efc70 100644 > > --- a/drivers/dma-buf/dma-fence.c > > +++ b/drivers/dma-buf/dma-fence.c > > @@ -110,6 +110,52 @@ u64 dma_fence_context_alloc(unsigned num) > > } > > EXPORT_SYMBOL(dma_fence_context_alloc); > > > > +#ifdef CONFIG_LOCKDEP > > +struct lockdep_map dma_fence_lockdep_map = { > > + .name = "dma_fence_map" > > +}; > > Not another false global sharing lockmap. It's a global contract, it needs a global lockdep map. And yes a big reason for the motivation here is that i915-gem has a tremendous urge to just redefine all these global locks to fit
Re: [RFC 01/17] dma-fence: add might_sleep annotation to _wait()
Am 12.05.20 um 10:59 schrieb Daniel Vetter: But only for non-zero timeout, to avoid false positives. One question here is whether the might_sleep should be unconditional, or only for real timeouts. I'm not sure, so went with the more defensive option. But in the interest of locking down the cross-driver dma_fence rules we might want to be more aggressive. Cc: linux-me...@vger.kernel.org Cc: linaro-mm-...@lists.linaro.org Cc: linux-r...@vger.kernel.org Cc: amd-...@lists.freedesktop.org Cc: intel-...@lists.freedesktop.org Cc: Chris Wilson Cc: Maarten Lankhorst Cc: Christian König Signed-off-by: Daniel Vetter --- drivers/dma-buf/dma-fence.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c index 052a41e2451c..6802125349fb 100644 --- a/drivers/dma-buf/dma-fence.c +++ b/drivers/dma-buf/dma-fence.c @@ -208,6 +208,9 @@ dma_fence_wait_timeout(struct dma_fence *fence, bool intr, signed long timeout) if (WARN_ON(timeout < 0)) return -EINVAL; + if (timeout > 0) + might_sleep(); + I would rather like to see might_sleep() called here all the time even with timeout==0. IIRC I removed the code in TTM abusing this in atomic context quite a while ago, but could be that some leaked in again or it is called in atomic context elsewhere as well. Christian. trace_dma_fence_wait_start(fence); if (fence->ops->wait) ret = fence->ops->wait(fence, intr, timeout); ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC 02/17] dma-fence: basic lockdep annotations
Quoting Daniel Vetter (2020-05-12 10:08:47) > On Tue, May 12, 2020 at 10:04:22AM +0100, Chris Wilson wrote: > > Quoting Daniel Vetter (2020-05-12 09:59:29) > > > Design is similar to the lockdep annotations for workers, but with > > > some twists: > > > > > > - We use a read-lock for the execution/worker/completion side, so that > > > this explicit annotation can be more liberally sprinkled around. > > > With read locks lockdep isn't going to complain if the read-side > > > isn't nested the same way under all circumstances, so ABBA deadlocks > > > are ok. Which they are, since this is an annotation only. > > > > > > - We're using non-recursive lockdep read lock mode, since in recursive > > > read lock mode lockdep does not catch read side hazards. And we > > > _very_ much want read side hazards to be caught. For full details of > > > this limitation see > > > > > > commit e91498589746065e3ae95d9a00b068e525eec34f > > > Author: Peter Zijlstra > > > Date: Wed Aug 23 13:13:11 2017 +0200 > > > > > > locking/lockdep/selftests: Add mixed read-write ABBA tests > > > > > > - To allow nesting of the read-side explicit annotations we explicitly > > > keep track of the nesting. lock_is_held() allows us to do that. > > > > > > - The wait-side annotation is a write lock, and entirely done within > > > dma_fence_wait() for everyone by default. > > > > > > - To be able to freely annotate helper functions I want to make it ok > > > to call dma_fence_begin/end_signalling from soft/hardirq context. > > > First attempt was using the hardirq locking context for the write > > > side in lockdep, but this forces all normal spinlocks nested within > > > dma_fence_begin/end_signalling to be spinlocks. That bollocks. > > > > > > The approach now is to simple check in_atomic(), and for these cases > > > entirely rely on the might_sleep() check in dma_fence_wait(). That > > > will catch any wrong nesting against spinlocks from soft/hardirq > > > contexts. > > > > > > The idea here is that every code path that's critical for eventually > > > signalling a dma_fence should be annotated with > > > dma_fence_begin/end_signalling. The annotation ideally starts right > > > after a dma_fence is published (added to a dma_resv, exposed as a > > > sync_file fd, attached to a drm_syncobj fd, or anything else that > > > makes the dma_fence visible to other kernel threads), up to and > > > including the dma_fence_wait(). Examples are irq handlers, the > > > scheduler rt threads, the tail of execbuf (after the corresponding > > > fences are visible), any workers that end up signalling dma_fences and > > > really anything else. Not annotated should be code paths that only > > > complete fences opportunistically as the gpu progresses, like e.g. > > > shrinker/eviction code. > > > > > > The main class of deadlocks this is supposed to catch are: > > > > > > Thread A: > > > > > > mutex_lock(A); > > > mutex_unlock(A); > > > > > > dma_fence_signal(); > > > > > > Thread B: > > > > > > mutex_lock(A); > > > dma_fence_wait(); > > > mutex_unlock(A); > > > > > > Thread B is blocked on A signalling the fence, but A never gets around > > > to that because it cannot acquire the lock A. > > > > > > Note that dma_fence_wait() is allowed to be nested within > > > dma_fence_begin/end_signalling sections. To allow this to happen the > > > read lock needs to be upgraded to a write lock, which means that any > > > other lock is acquired between the dma_fence_begin_signalling() call and > > > the call to dma_fence_wait(), and still held, this will result in an > > > immediate lockdep complaint. The only other option would be to not > > > annotate such calls, defeating the point. Therefore these annotations > > > cannot be sprinkled over the code entirely mindless to avoid false > > > positives. > > > > > > v2: handle soft/hardirq ctx better against write side and dont forget > > > EXPORT_SYMBOL, drivers can't use this otherwise. > > > > > > Cc: linux-me...@vger.kernel.org > > > Cc: linaro-mm-...@lists.linaro.org > > > Cc: linux-r...@vger.kernel.org > > > Cc: amd-...@lists.freedesktop.org > > > Cc: intel-...@lists.freedesktop.org > > > Cc: Chris Wilson > > > Cc: Maarten Lankhorst > > > Cc: Christian König > > > Signed-off-by: Daniel Vetter > > > --- > > > drivers/dma-buf/dma-fence.c | 53 + > > > include/linux/dma-fence.h | 12 + > > > 2 files changed, 65 insertions(+) > > > > > > diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c > > > index 6802125349fb..d5c0fd2efc70 100644 > > > --- a/drivers/dma-buf/dma-fence.c > > > +++ b/drivers/dma-buf/dma-fence.c > > > @@ -110,6 +110,52 @@ u64 dma_fence_context_alloc(unsigned num) > > > } > > > EXPORT_SYMBOL(dma_fence_context_alloc); > > > > > > +#ifdef CONFIG_LOCKDEP > > > +struct lockdep_map dma_fence_lockdep_map = { > > > + .name
Re: [RFC] Remove AGP support from Radeon/Nouveau/TTM
Hi David! On 5/12/20 7:04 AM, David VANTYGHEM wrote: > Im happy now that after your work, Debian and GRUB install fine on my > iMac G3. But Xserver doesn't start, I've got an AMD Rage 128 Pro AGP 4x > (see joined screenshot). This is an unrelated problem as the reason why you don't have a working graphics driver at the moment is because Debian's X.org maintainers removed a couple of older drivers from the package archive - without knowing these drivers are still used by PowerPC users. I will take over package maintainership of these drivers soon and re-upload them to the Debian archive. Adrian -- .''`. John Paul Adrian Glaubitz : :' : Debian Developer - glaub...@debian.org `. `' Freie Universitaet Berlin - glaub...@physik.fu-berlin.de `-GPG: 62FF 8A75 84E0 2956 9546 0006 7426 3B37 F5B5 F913 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH V4 2/3] drm/vkms: Compute CRC without change input data
Hi Rodrigo, On Mon, 11 May 2020 at 12:55, Rodrigo Siqueira wrote: > > From: Rodrigo Siqueira > > The compute_crc() function is responsible for calculating the > framebuffer CRC value; due to the XRGB format, this function has to > ignore the alpha channel during the CRC computation. Therefore, > compute_crc() set zero to the alpha channel directly in the input > framebuffer, which is not a problem since this function receives a copy > of the original buffer. However, if we want to use this function in a > context without a buffer copy, it will change the initial value. This > patch makes compute_crc() calculate the CRC value without modifying the > input framebuffer. > > Signed-off-by: Rodrigo Siqueira > --- > drivers/gpu/drm/vkms/vkms_composer.c | 31 +--- > 1 file changed, 19 insertions(+), 12 deletions(-) > > diff --git a/drivers/gpu/drm/vkms/vkms_composer.c > b/drivers/gpu/drm/vkms/vkms_composer.c > index 258e659ecfba..686d25e7b01d 100644 > --- a/drivers/gpu/drm/vkms/vkms_composer.c > +++ b/drivers/gpu/drm/vkms/vkms_composer.c > @@ -9,33 +9,40 @@ > > #include "vkms_drv.h" > > +static u32 get_pixel_from_buffer(int x, int y, const u8 *buffer, > +const struct vkms_composer *composer) > +{ > + int src_offset = composer->offset + (y * composer->pitch) > + + (x * composer->cpp); > + > + return *(u32 *)[src_offset]; > +} > + > /** > * compute_crc - Compute CRC value on output frame > * > - * @vaddr_out: address to final framebuffer > + * @vaddr: address to final framebuffer > * @composer: framebuffer's metadata > * > * returns CRC value computed using crc32 on the visible portion of > * the final framebuffer at vaddr_out > */ > -static uint32_t compute_crc(void *vaddr_out, struct vkms_composer *composer) > +static uint32_t compute_crc(const u8 *vaddr, > + const struct vkms_composer *composer) > { > - int i, j, src_offset; > + int x, y; > int x_src = composer->src.x1 >> 16; > int y_src = composer->src.y1 >> 16; > int h_src = drm_rect_height(>src) >> 16; > int w_src = drm_rect_width(>src) >> 16; > - u32 crc = 0; > + u32 crc = 0, pixel = 0; > > - for (i = y_src; i < y_src + h_src; ++i) { > - for (j = x_src; j < x_src + w_src; ++j) { > - src_offset = composer->offset > -+ (i * composer->pitch) > -+ (j * composer->cpp); > + for (y = y_src; y < y_src + h_src; ++y) { > + for (x = x_src; x < x_src + w_src; ++x) { > /* XRGB format ignores Alpha channel */ > - memset(vaddr_out + src_offset + 24, 0, 8); > - crc = crc32_le(crc, vaddr_out + src_offset, > - sizeof(u32)); > + pixel = get_pixel_from_buffer(x, y, vaddr, composer); > + bitmap_clear((void *), 0, 8); > + crc = crc32_le(crc, (void *), sizeof(u32)); > } > } > IMHO using something like the following makes the code far simpler and clearer. offset = composer->offset + (y_src * composer->pitch) + (x_src * composer->cpp); for (i = 0; i < h_src; i++, offset += composer->pitch) { for (j = 0; j < w_src; j++, offset += composer->cpp) { pixel = get_pixel_from_buffer(vaddr, offset); crc = crc32_le(crc, , sizeof(u32); // cast should not be needed } } With the bitmap_clear() and related comment moved into get_pixel_from_buffer(). -Emil ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH -next v2] drm/mcde: dsi: Fix return value check in mcde_dsi_bind()
On Thu, Apr 30, 2020 at 9:30 AM Wei Yongjun wrote: > The of_drm_find_bridge() function returns NULL on error, it doesn't return > error pointers so this check doesn't work. > > Fixes: 5fc537bfd000 ("drm/mcde: Add new driver for ST-Ericsson MCDE") > Signed-off-by: Wei Yongjun > --- > v1 - > v2: add fixes and fix the subject Already applied v1, no big deal anyways, its a nonurgent fix. Yours, Linus Walleij ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v4 01/38] dma-mapping: add generic helpers for mapping sgtable objects
Hi Christoph, On 12.05.2020 15:09, Christoph Hellwig wrote: > On Tue, May 12, 2020 at 03:00:31PM +0200, Marek Szyprowski wrote: >>> if (n <= 0) >>> return -EINVAL; >>> sgt->nents = n; >>> return 0; >>> >> Indeed this version looks much better. I will resend it in a few minutes. > I could also just fix it up when applying the patch. Fine for me. Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v4 33/38] staging: tegra-vde: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that the dma_map_sg() function returns the number of the created entries in the DMA address space. However the subsequent calls to the dma_sync_sg_for_{device,cpu}() and dma_unmap_sg must be called with the original number of the entries passed to the dma_map_sg(). struct sg_table is a common structure used for describing a non-contiguous memory buffer, used commonly in the DRM and graphics subsystems. It consists of a scatterlist with memory pages and DMA addresses (sgl entry), as well as the number of scatterlist entries: CPU pages (orig_nents entry) and DMA mapped pages (nents entry). It turned out that it was a common mistake to misuse nents and orig_nents entries, calling DMA-mapping functions with a wrong number of entries or ignoring the number of mapped entries returned by the dma_map_sg() function. To avoid such issues, lets use a common dma-mapping wrappers operating directly on the struct sg_table objects and use scatterlist page iterators where possible. This, almost always, hides references to the nents and orig_nents entries, making the code robust, easier to follow and copy/paste safe. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v4 00/38] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lore.kernel.org/dri-devel/20200512085710.14688-1-m.szyprow...@samsung.com/T/ --- drivers/staging/media/tegra-vde/iommu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/tegra-vde/iommu.c b/drivers/staging/media/tegra-vde/iommu.c index 6af863d..adf8dc7 100644 --- a/drivers/staging/media/tegra-vde/iommu.c +++ b/drivers/staging/media/tegra-vde/iommu.c @@ -36,8 +36,8 @@ int tegra_vde_iommu_map(struct tegra_vde *vde, addr = iova_dma_addr(>iova, iova); - size = iommu_map_sg(vde->domain, addr, sgt->sgl, sgt->nents, - IOMMU_READ | IOMMU_WRITE); + size = iommu_map_sgtable(vde->domain, addr, sgt, +IOMMU_READ | IOMMU_WRITE); if (!size) { __free_iova(>iova, iova); return -ENXIO; -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v4 37/38] media: pci: fix common ALSA DMA-mapping related codes
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. Adapt the code to obey those rules. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v4 00/38] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lore.kernel.org/dri-devel/20200512085710.14688-1-m.szyprow...@samsung.com/T/ --- drivers/media/pci/cx23885/cx23885-alsa.c | 2 +- drivers/media/pci/cx25821/cx25821-alsa.c | 2 +- drivers/media/pci/cx88/cx88-alsa.c | 2 +- drivers/media/pci/saa7134/saa7134-alsa.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/pci/cx23885/cx23885-alsa.c b/drivers/media/pci/cx23885/cx23885-alsa.c index df44ed7..3f366e4 100644 --- a/drivers/media/pci/cx23885/cx23885-alsa.c +++ b/drivers/media/pci/cx23885/cx23885-alsa.c @@ -129,7 +129,7 @@ static int cx23885_alsa_dma_unmap(struct cx23885_audio_dev *dev) if (!buf->sglen) return 0; - dma_unmap_sg(>pci->dev, buf->sglist, buf->sglen, PCI_DMA_FROMDEVICE); + dma_unmap_sg(>pci->dev, buf->sglist, buf->nr_pages, PCI_DMA_FROMDEVICE); buf->sglen = 0; return 0; } diff --git a/drivers/media/pci/cx25821/cx25821-alsa.c b/drivers/media/pci/cx25821/cx25821-alsa.c index 3016164..c40304d 100644 --- a/drivers/media/pci/cx25821/cx25821-alsa.c +++ b/drivers/media/pci/cx25821/cx25821-alsa.c @@ -193,7 +193,7 @@ static int cx25821_alsa_dma_unmap(struct cx25821_audio_dev *dev) if (!buf->sglen) return 0; - dma_unmap_sg(>pci->dev, buf->sglist, buf->sglen, PCI_DMA_FROMDEVICE); + dma_unmap_sg(>pci->dev, buf->sglist, buf->nr_pages, PCI_DMA_FROMDEVICE); buf->sglen = 0; return 0; } diff --git a/drivers/media/pci/cx88/cx88-alsa.c b/drivers/media/pci/cx88/cx88-alsa.c index 7d7acee..3c6fe6c 100644 --- a/drivers/media/pci/cx88/cx88-alsa.c +++ b/drivers/media/pci/cx88/cx88-alsa.c @@ -332,7 +332,7 @@ static int cx88_alsa_dma_unmap(struct cx88_audio_dev *dev) if (!buf->sglen) return 0; - dma_unmap_sg(>pci->dev, buf->sglist, buf->sglen, + dma_unmap_sg(>pci->dev, buf->sglist, buf->nr_pages, PCI_DMA_FROMDEVICE); buf->sglen = 0; return 0; diff --git a/drivers/media/pci/saa7134/saa7134-alsa.c b/drivers/media/pci/saa7134/saa7134-alsa.c index 544ca57..398c47f 100644 --- a/drivers/media/pci/saa7134/saa7134-alsa.c +++ b/drivers/media/pci/saa7134/saa7134-alsa.c @@ -313,7 +313,7 @@ static int saa7134_alsa_dma_unmap(struct saa7134_dev *dev) if (!dma->sglen) return 0; - dma_unmap_sg(>pci->dev, dma->sglist, dma->sglen, PCI_DMA_FROMDEVICE); + dma_unmap_sg(>pci->dev, dma->sglist, dma->nr_pages, PCI_DMA_FROMDEVICE); dma->sglen = 0; return 0; } -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v4 19/38] drm: panfrost: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that the dma_map_sg() function returns the number of the created entries in the DMA address space. However the subsequent calls to the dma_sync_sg_for_{device,cpu}() and dma_unmap_sg must be called with the original number of the entries passed to the dma_map_sg(). struct sg_table is a common structure used for describing a non-contiguous memory buffer, used commonly in the DRM and graphics subsystems. It consists of a scatterlist with memory pages and DMA addresses (sgl entry), as well as the number of scatterlist entries: CPU pages (orig_nents entry) and DMA mapped pages (nents entry). It turned out that it was a common mistake to misuse nents and orig_nents entries, calling DMA-mapping functions with a wrong number of entries or ignoring the number of mapped entries returned by the dma_map_sg() function. To avoid such issues, lets use a common dma-mapping wrappers operating directly on the struct sg_table objects and use scatterlist page iterators where possible. This, almost always, hides references to the nents and orig_nents entries, making the code robust, easier to follow and copy/paste safe. Signed-off-by: Marek Szyprowski Reviewed-by: Steven Price --- For more information, see '[PATCH v4 00/38] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lore.kernel.org/dri-devel/20200512085710.14688-1-m.szyprow...@samsung.com/T/ --- drivers/gpu/drm/panfrost/panfrost_gem.c | 4 ++-- drivers/gpu/drm/panfrost/panfrost_mmu.c | 7 +++ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c index 17b654e..6696304 100644 --- a/drivers/gpu/drm/panfrost/panfrost_gem.c +++ b/drivers/gpu/drm/panfrost/panfrost_gem.c @@ -41,8 +41,8 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj) for (i = 0; i < n_sgt; i++) { if (bo->sgts[i].sgl) { - dma_unmap_sg(pfdev->dev, bo->sgts[i].sgl, -bo->sgts[i].nents, DMA_BIDIRECTIONAL); + dma_unmap_sgtable(pfdev->dev, >sgts[i], + DMA_BIDIRECTIONAL, 0); sg_free_table(>sgts[i]); } } diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c index ed28aeb..eb2550e 100644 --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c @@ -253,7 +253,7 @@ static int mmu_map_sg(struct panfrost_device *pfdev, struct panfrost_mmu *mmu, struct io_pgtable_ops *ops = mmu->pgtbl_ops; u64 start_iova = iova; - for_each_sg(sgt->sgl, sgl, sgt->nents, count) { + for_each_sgtable_dma_sg(sgt, sgl, count) { unsigned long paddr = sg_dma_address(sgl); size_t len = sg_dma_len(sgl); @@ -517,10 +517,9 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as, if (ret) goto err_pages; - if (!dma_map_sg(pfdev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL)) { - ret = -EINVAL; + ret = dma_map_sgtable(pfdev->dev, sgt, DMA_BIDIRECTIONAL, 0); + if (ret) goto err_map; - } mmu_map_sg(pfdev, bomapping->mmu, addr, IOMMU_WRITE | IOMMU_READ | IOMMU_NOEXEC, sgt); -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v4 18/38] drm: omapdrm: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that the dma_map_sg() function returns the number of the created entries in the DMA address space. However the subsequent calls to the dma_sync_sg_for_{device,cpu}() and dma_unmap_sg must be called with the original number of the entries passed to the dma_map_sg(). struct sg_table is a common structure used for describing a non-contiguous memory buffer, used commonly in the DRM and graphics subsystems. It consists of a scatterlist with memory pages and DMA addresses (sgl entry), as well as the number of scatterlist entries: CPU pages (orig_nents entry) and DMA mapped pages (nents entry). It turned out that it was a common mistake to misuse nents and orig_nents entries, calling DMA-mapping functions with a wrong number of entries or ignoring the number of mapped entries returned by the dma_map_sg() function. Fix the code to refer to proper nents or orig_nents entries. This driver checks for a buffer contiguity in DMA address space, so it should test sg_table->nents entry. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v4 00/38] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lore.kernel.org/dri-devel/20200512085710.14688-1-m.szyprow...@samsung.com/T/ --- drivers/gpu/drm/omapdrm/omap_gem.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index c259411..cbcb361 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -48,7 +48,7 @@ struct omap_gem_object { * OMAP_BO_MEM_DMA_API flag set) * * - buffers imported from dmabuf (with the OMAP_BO_MEM_DMABUF flag set) -* if they are physically contiguous (when sgt->orig_nents == 1) +* if they are physically contiguous (when sgt->nents == 1) * * - buffers mapped through the TILER when dma_addr_cnt is not zero, in * which case the DMA address points to the TILER aperture @@ -1279,7 +1279,7 @@ struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size, union omap_gem_size gsize; /* Without a DMM only physically contiguous buffers can be supported. */ - if (sgt->orig_nents != 1 && !priv->has_dmm) + if (sgt->nents != 1 && !priv->has_dmm) return ERR_PTR(-EINVAL); gsize.bytes = PAGE_ALIGN(size); @@ -1293,7 +1293,7 @@ struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size, omap_obj->sgt = sgt; - if (sgt->orig_nents == 1) { + if (sgt->nents == 1) { omap_obj->dma_addr = sg_dma_address(sgt->sgl); } else { /* Create pages list from sgt */ -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 12/15] drm/mgag200: Remove out-commented suspend/resume helpers
Hi Thomas, On Tue, 12 May 2020 at 09:43, Thomas Zimmermann wrote: > > The suspend/resume helpers are unused. Also remove associated state > from struct mga_device. > Although DPMS in it's traditional sense is no longer a thing, would it make sense to keep this around for documentation purposes? In particular, the pci magic and associated PLL/DAC/pixel clock could be used for dynamic PM. -Emil ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v4 30/38] dmabuf: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that the dma_map_sg() function returns the number of the created entries in the DMA address space. However the subsequent calls to the dma_sync_sg_for_{device,cpu}() and dma_unmap_sg must be called with the original number of the entries passed to the dma_map_sg(). struct sg_table is a common structure used for describing a non-contiguous memory buffer, used commonly in the DRM and graphics subsystems. It consists of a scatterlist with memory pages and DMA addresses (sgl entry), as well as the number of scatterlist entries: CPU pages (orig_nents entry) and DMA mapped pages (nents entry). It turned out that it was a common mistake to misuse nents and orig_nents entries, calling DMA-mapping functions with a wrong number of entries or ignoring the number of mapped entries returned by the dma_map_sg() function. To avoid such issues, lets use a common dma-mapping wrappers operating directly on the struct sg_table objects and use scatterlist page iterators where possible. This, almost always, hides references to the nents and orig_nents entries, making the code robust, easier to follow and copy/paste safe. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v4 00/38] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lore.kernel.org/dri-devel/20200512085710.14688-1-m.szyprow...@samsung.com/T/ --- drivers/dma-buf/heaps/heap-helpers.c | 13 ++--- drivers/dma-buf/udmabuf.c| 7 +++ 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/dma-buf/heaps/heap-helpers.c b/drivers/dma-buf/heaps/heap-helpers.c index 9f964ca..be9523a 100644 --- a/drivers/dma-buf/heaps/heap-helpers.c +++ b/drivers/dma-buf/heaps/heap-helpers.c @@ -140,13 +140,12 @@ struct sg_table *dma_heap_map_dma_buf(struct dma_buf_attachment *attachment, enum dma_data_direction direction) { struct dma_heaps_attachment *a = attachment->priv; - struct sg_table *table; - - table = >table; + struct sg_table *table = >table; + int ret; - if (!dma_map_sg(attachment->dev, table->sgl, table->nents, - direction)) - table = ERR_PTR(-ENOMEM); + ret = dma_map_sgtable(attachment->dev, table, direction); + if (ret) + table = ERR_PTR(ret); return table; } @@ -154,7 +153,7 @@ static void dma_heap_unmap_dma_buf(struct dma_buf_attachment *attachment, struct sg_table *table, enum dma_data_direction direction) { - dma_unmap_sg(attachment->dev, table->sgl, table->nents, direction); + dma_unmap_sgtable(attachment->dev, table, direction); } static vm_fault_t dma_heap_vm_fault(struct vm_fault *vmf) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index acb26c6..5bcbf7a 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -63,10 +63,9 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf, GFP_KERNEL); if (ret < 0) goto err; - if (!dma_map_sg(dev, sg->sgl, sg->nents, direction)) { - ret = -EINVAL; + ret = dma_map_sgtable(dev, sg, direction); + if (ret < 0) goto err; - } return sg; err: @@ -78,7 +77,7 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf, static void put_sg_table(struct device *dev, struct sg_table *sg, enum dma_data_direction direction) { - dma_unmap_sg(dev, sg->sgl, sg->nents, direction); + dma_unmap_sgtable(dev, sg, direction); sg_free_table(sg); kfree(sg); } -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v4 28/38] drm: host1x: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that the dma_map_sg() function returns the number of the created entries in the DMA address space. However the subsequent calls to the dma_sync_sg_for_{device,cpu}() and dma_unmap_sg must be called with the original number of the entries passed to the dma_map_sg(). struct sg_table is a common structure used for describing a non-contiguous memory buffer, used commonly in the DRM and graphics subsystems. It consists of a scatterlist with memory pages and DMA addresses (sgl entry), as well as the number of scatterlist entries: CPU pages (orig_nents entry) and DMA mapped pages (nents entry). It turned out that it was a common mistake to misuse nents and orig_nents entries, calling DMA-mapping functions with a wrong number of entries or ignoring the number of mapped entries returned by the dma_map_sg() function. To avoid such issues, lets use a common dma-mapping wrappers operating directly on the struct sg_table objects and use scatterlist page iterators where possible. This, almost always, hides references to the nents and orig_nents entries, making the code robust, easier to follow and copy/paste safe. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v4 00/38] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lore.kernel.org/dri-devel/20200512085710.14688-1-m.szyprow...@samsung.com/T/ --- drivers/gpu/host1x/job.c | 22 -- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c index a10643a..4832b57 100644 --- a/drivers/gpu/host1x/job.c +++ b/drivers/gpu/host1x/job.c @@ -166,11 +166,9 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job) goto unpin; } - err = dma_map_sg(dev, sgt->sgl, sgt->nents, dir); - if (!err) { - err = -ENOMEM; + err = dma_map_sgtable(dev, sgt, dir, 0); + if (err) goto unpin; - } job->unpins[job->num_unpins].dev = dev; job->unpins[job->num_unpins].dir = dir; @@ -217,7 +215,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job) } if (!IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL) && host->domain) { - for_each_sg(sgt->sgl, sg, sgt->nents, j) + for_each_sgtable_sg(sgt, sg, j) gather_size += sg->length; gather_size = iova_align(>iova, gather_size); @@ -229,9 +227,9 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job) goto unpin; } - err = iommu_map_sg(host->domain, + err = iommu_map_sgtable(host->domain, iova_dma_addr(>iova, alloc), - sgt->sgl, sgt->nents, IOMMU_READ); + sgt, IOMMU_READ); if (err == 0) { __free_iova(>iova, alloc); err = -EINVAL; @@ -241,12 +239,9 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job) job->unpins[job->num_unpins].size = gather_size; phys_addr = iova_dma_addr(>iova, alloc); } else if (sgt) { - err = dma_map_sg(host->dev, sgt->sgl, sgt->nents, -DMA_TO_DEVICE); - if (!err) { - err = -ENOMEM; + err = dma_map_sgtable(host->dev, sgt, DMA_TO_DEVICE, 0); + if (err) goto unpin; - } job->unpins[job->num_unpins].dir = DMA_TO_DEVICE; job->unpins[job->num_unpins].dev = host->dev; @@ -647,8 +642,7 @@ void host1x_job_unpin(struct host1x_job *job) } if (unpin->dev && sgt) - dma_unmap_sg(unpin->dev, sgt->sgl, sgt->nents, -unpin->dir); + dma_unmap_sgtable(unpin->dev, sgt, unpin->dir, 0); host1x_bo_unpin(dev, unpin->bo, sgt); host1x_bo_put(unpin->bo); -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v4 36/38] samples: vfio-mdev/mbochs: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that the dma_map_sg() function returns the number of the created entries in the DMA address space. However the subsequent calls to the dma_sync_sg_for_{device,cpu}() and dma_unmap_sg must be called with the original number of the entries passed to the dma_map_sg(). struct sg_table is a common structure used for describing a non-contiguous memory buffer, used commonly in the DRM and graphics subsystems. It consists of a scatterlist with memory pages and DMA addresses (sgl entry), as well as the number of scatterlist entries: CPU pages (orig_nents entry) and DMA mapped pages (nents entry). It turned out that it was a common mistake to misuse nents and orig_nents entries, calling DMA-mapping functions with a wrong number of entries or ignoring the number of mapped entries returned by the dma_map_sg() function. To avoid such issues, lets use a common dma-mapping wrappers operating directly on the struct sg_table objects and use scatterlist page iterators where possible. This, almost always, hides references to the nents and orig_nents entries, making the code robust, easier to follow and copy/paste safe. While touching this code, also add missing call to dma_unmap_sgtable. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v4 00/38] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lore.kernel.org/dri-devel/20200512085710.14688-1-m.szyprow...@samsung.com/T/ --- samples/vfio-mdev/mbochs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c index 3cc5e59..f2c62e0 100644 --- a/samples/vfio-mdev/mbochs.c +++ b/samples/vfio-mdev/mbochs.c @@ -846,7 +846,7 @@ static struct sg_table *mbochs_map_dmabuf(struct dma_buf_attachment *at, if (sg_alloc_table_from_pages(sg, dmabuf->pages, dmabuf->pagecount, 0, dmabuf->mode.size, GFP_KERNEL) < 0) goto err2; - if (!dma_map_sg(at->dev, sg->sgl, sg->nents, direction)) + if (dma_map_sgtable(at->dev, sg, direction)) goto err3; return sg; @@ -868,6 +868,7 @@ static void mbochs_unmap_dmabuf(struct dma_buf_attachment *at, dev_dbg(dev, "%s: %d\n", __func__, dmabuf->id); + dma_unmap_sgtable(at->dev, sg, direction); sg_free_table(sg); kfree(sg); } -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v4 23/38] drm: tegra: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that the dma_map_sg() function returns the number of the created entries in the DMA address space. However the subsequent calls to the dma_sync_sg_for_{device,cpu}() and dma_unmap_sg must be called with the original number of the entries passed to the dma_map_sg(). struct sg_table is a common structure used for describing a non-contiguous memory buffer, used commonly in the DRM and graphics subsystems. It consists of a scatterlist with memory pages and DMA addresses (sgl entry), as well as the number of scatterlist entries: CPU pages (orig_nents entry) and DMA mapped pages (nents entry). It turned out that it was a common mistake to misuse nents and orig_nents entries, calling DMA-mapping functions with a wrong number of entries or ignoring the number of mapped entries returned by the dma_map_sg() function. To avoid such issues, lets use a common dma-mapping wrappers operating directly on the struct sg_table objects and use scatterlist page iterators where possible. This, almost always, hides references to the nents and orig_nents entries, making the code robust, easier to follow and copy/paste safe. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v4 00/38] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lore.kernel.org/dri-devel/20200512085710.14688-1-m.szyprow...@samsung.com/T/ --- drivers/gpu/drm/tegra/gem.c | 27 ++- drivers/gpu/drm/tegra/plane.c | 15 +-- 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index 6237681..2169130 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -98,8 +98,8 @@ static struct sg_table *tegra_bo_pin(struct device *dev, struct host1x_bo *bo, * the SG table needs to be copied to avoid overwriting any * other potential users of the original SG table. */ - err = sg_alloc_table_from_sg(sgt, obj->sgt->sgl, obj->sgt->nents, -GFP_KERNEL); + err = sg_alloc_table_from_sg(sgt, obj->sgt->sgl, +obj->sgt->orig_nents, GFP_KERNEL); if (err < 0) goto free; } else { @@ -196,8 +196,7 @@ static int tegra_bo_iommu_map(struct tegra_drm *tegra, struct tegra_bo *bo) bo->iova = bo->mm->start; - bo->size = iommu_map_sg(tegra->domain, bo->iova, bo->sgt->sgl, - bo->sgt->nents, prot); + bo->size = iommu_map_sgtable(tegra->domain, bo->iova, bo->sgt, prot); if (!bo->size) { dev_err(tegra->drm->dev, "failed to map buffer\n"); err = -ENOMEM; @@ -264,8 +263,7 @@ static struct tegra_bo *tegra_bo_alloc_object(struct drm_device *drm, static void tegra_bo_free(struct drm_device *drm, struct tegra_bo *bo) { if (bo->pages) { - dma_unmap_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents, -DMA_FROM_DEVICE); + dma_unmap_sgtable(drm->dev, bo->sgt, DMA_FROM_DEVICE, 0); drm_gem_put_pages(>gem, bo->pages, true, true); sg_free_table(bo->sgt); kfree(bo->sgt); @@ -290,12 +288,9 @@ static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo) goto put_pages; } - err = dma_map_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents, -DMA_FROM_DEVICE); - if (err == 0) { - err = -EFAULT; + err = dma_map_sgtable(drm->dev, bo->sgt, DMA_FROM_DEVICE, 0); + if (err) goto free_sgt; - } return 0; @@ -571,7 +566,7 @@ int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma) goto free; } - if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0) + if (dma_map_sgtable(attach->dev, sgt, dir, 0)) goto free; return sgt; @@ -590,7 +585,7 @@ static void tegra_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach, struct tegra_bo *bo = to_tegra_bo(gem); if (bo->pages) - dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir); + dma_unmap_sgtable(attach->dev, sgt, dir, 0); sg_free_table(sgt); kfree(sgt); @@ -609,8 +604,7 @@ static int tegra_gem_prime_begin_cpu_access(struct dma_buf *buf, struct drm_device *drm = gem->dev; if (bo->pages) - dma_sync_sg_for_cpu(drm->dev, bo->sgt->sgl, bo->sgt->nents, - DMA_FROM_DEVICE); + dma_sync_sgtable_for_cpu(drm->dev, bo->sgt, DMA_FROM_DEVICE); return 0; } @@ -623,8 +617,7 @@ static int tegra_gem_prime_end_cpu_access(struct dma_buf *buf, struct drm_device *drm = gem->dev; if (bo->pages) -
Re: [RFC 01/17] dma-fence: add might_sleep annotation to _wait()
Quoting Daniel Vetter (2020-05-12 09:59:28) > But only for non-zero timeout, to avoid false positives. > > One question here is whether the might_sleep should be unconditional, > or only for real timeouts. I'm not sure, so went with the more > defensive option. But in the interest of locking down the cross-driver > dma_fence rules we might want to be more aggressive. You can argue for enforcing might_sleep() as internal queries should be using dma_fence_is_signaled() and not dma_fence_wait_timeout(0). > Cc: linux-me...@vger.kernel.org > Cc: linaro-mm-...@lists.linaro.org > Cc: linux-r...@vger.kernel.org > Cc: amd-...@lists.freedesktop.org > Cc: intel-...@lists.freedesktop.org > Cc: Chris Wilson > Cc: Maarten Lankhorst > Cc: Christian König > Signed-off-by: Daniel Vetter > --- > drivers/dma-buf/dma-fence.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c > index 052a41e2451c..6802125349fb 100644 > --- a/drivers/dma-buf/dma-fence.c > +++ b/drivers/dma-buf/dma-fence.c > @@ -208,6 +208,9 @@ dma_fence_wait_timeout(struct dma_fence *fence, bool > intr, signed long timeout) > if (WARN_ON(timeout < 0)) > return -EINVAL; > > + if (timeout > 0) > + might_sleep(); might_sleep_if(timeout > 0); -Chris ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v4 08/38] drm: armada: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that the dma_map_sg() function returns the number of the created entries in the DMA address space. However the subsequent calls to the dma_sync_sg_for_{device,cpu}() and dma_unmap_sg must be called with the original number of the entries passed to the dma_map_sg(). struct sg_table is a common structure used for describing a non-contiguous memory buffer, used commonly in the DRM and graphics subsystems. It consists of a scatterlist with memory pages and DMA addresses (sgl entry), as well as the number of scatterlist entries: CPU pages (orig_nents entry) and DMA mapped pages (nents entry). It turned out that it was a common mistake to misuse nents and orig_nents entries, calling DMA-mapping functions with a wrong number of entries or ignoring the number of mapped entries returned by the dma_map_sg() function. To avoid such issues, lets use a common dma-mapping wrappers operating directly on the struct sg_table objects and use scatterlist page iterators where possible. This, almost always, hides references to the nents and orig_nents entries, making the code robust, easier to follow and copy/paste safe. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v4 00/38] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lore.kernel.org/dri-devel/20200512085710.14688-1-m.szyprow...@samsung.com/T/ --- drivers/gpu/drm/armada/armada_gem.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c index 976685f..0d61da5 100644 --- a/drivers/gpu/drm/armada/armada_gem.c +++ b/drivers/gpu/drm/armada/armada_gem.c @@ -395,7 +395,7 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data, mapping = dobj->obj.filp->f_mapping; - for_each_sg(sgt->sgl, sg, count, i) { + for_each_sgtable_sg(sgt, sg, i) { struct page *page; page = shmem_read_mapping_page(mapping, i); @@ -407,8 +407,8 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data, sg_set_page(sg, page, PAGE_SIZE, 0); } - if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0) { - num = sgt->nents; + if (dma_map_sgtable(attach->dev, sgt, dir, 0)) { + num = count; goto release; } } else if (dobj->page) { @@ -418,7 +418,7 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data, sg_set_page(sgt->sgl, dobj->page, dobj->obj.size, 0); - if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0) + if (dma_map_sgtable(attach->dev, sgt, dir, 0)) goto free_table; } else if (dobj->linear) { /* Single contiguous physical region - no struct page */ @@ -449,11 +449,11 @@ static void armada_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach, int i; if (!dobj->linear) - dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir); + dma_unmap_sgtable(attach->dev, sgt, dir, 0); if (dobj->obj.filp) { struct scatterlist *sg; - for_each_sg(sgt->sgl, sg, sgt->nents, i) + for_each_sgtable_sg(sgt, sg, i) put_page(sg_page(sg)); } -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v4 14/38] drm: mediatek: use common helper for a scatterlist contiguity check
Use common helper for checking the contiguity of the imported dma-buf and do this check before allocating resources, so the error path is simpler. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v4 00/38] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lore.kernel.org/dri-devel/20200512085710.14688-1-m.szyprow...@samsung.com/T/ --- drivers/gpu/drm/mediatek/mtk_drm_gem.c | 25 ++--- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c index b04a3c2..6c34c06 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c @@ -212,34 +212,21 @@ struct drm_gem_object *mtk_gem_prime_import_sg_table(struct drm_device *dev, struct dma_buf_attachment *attach, struct sg_table *sg) { struct mtk_drm_gem_obj *mtk_gem; - int ret; - struct scatterlist *s; - unsigned int i; - dma_addr_t expected; - mtk_gem = mtk_drm_gem_init(dev, attach->dmabuf->size); + /* check if the entries in the sg_table are contiguous */ + if (drm_prime_get_contiguous_size(sg) < attach->dmabuf->size) { + DRM_ERROR("sg_table is not contiguous"); + return ERR_PTR(-EINVAL); + } + mtk_gem = mtk_drm_gem_init(dev, attach->dmabuf->size); if (IS_ERR(mtk_gem)) return ERR_CAST(mtk_gem); - expected = sg_dma_address(sg->sgl); - for_each_sg(sg->sgl, s, sg->nents, i) { - if (sg_dma_address(s) != expected) { - DRM_ERROR("sg_table is not contiguous"); - ret = -EINVAL; - goto err_gem_free; - } - expected = sg_dma_address(s) + sg_dma_len(s); - } - mtk_gem->dma_addr = sg_dma_address(sg->sgl); mtk_gem->sg = sg; return _gem->base; - -err_gem_free: - kfree(mtk_gem); - return ERR_PTR(ret); } void *mtk_drm_gem_prime_vmap(struct drm_gem_object *obj) -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH -next] drm/mcde: dsi: Fix return value check in dev_err()
On Tue, Apr 28, 2020 at 4:13 PM Wei Yongjun wrote: > In case of error, the function of_drm_find_bridge() returns NULL pointer > not ERR_PTR(). The IS_ERR() test in the return value check should be > replaced with NULL test. > > Signed-off-by: Wei Yongjun Patch applied! Thanks Wei, sorry for the long delay. Yours, Linus Walleij ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel