Re: [PATCH] drm/exec, drm/gpuvm: Prefer u32 over uint32_t
Hi, On 1/19/24 16:32, Jani Nikula wrote: On Fri, 19 Jan 2024, Lucas De Marchi wrote: On Fri, Jan 19, 2024 at 10:05:57AM +0100, Thomas Hellström wrote: The relatively recently introduced drm/exec utility was using uint32_t in its interface, which was then also carried over to drm/gpuvm. Prefer u32 in new code and update drm/exec and drm/gpuvm accordingly. Cc: Christian König Cc: Danilo Krummrich Signed-off-by: Thomas Hellström --- drivers/gpu/drm/drm_exec.c | 2 +- include/drm/drm_exec.h | 4 ++-- include/drm/drm_gpuvm.h| 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) Reviewed-by: Lucas De Marchi I was surprised we have quite a few places using the c99 types rather than kernel types. $ git grep -ce uint[0-9][0-9]_t drivers/gpu/drm/*.c drivers/gpu/drm/drm_atomic.c:1 drivers/gpu/drm/drm_atomic_helper.c:7 drivers/gpu/drm/drm_atomic_state_helper.c:1 drivers/gpu/drm/drm_atomic_uapi.c:17 drivers/gpu/drm/drm_color_mgmt.c:4 drivers/gpu/drm/drm_connector.c:6 drivers/gpu/drm/drm_crtc.c:3 drivers/gpu/drm/drm_damage_helper.c:2 drivers/gpu/drm/drm_debugfs_crc.c:1 drivers/gpu/drm/drm_exec.c:1 drivers/gpu/drm/drm_fb_helper.c:10 drivers/gpu/drm/drm_format_helper.c:6 drivers/gpu/drm/drm_fourcc.c:6 drivers/gpu/drm/drm_framebuffer.c:5 drivers/gpu/drm/drm_gem.c:1 drivers/gpu/drm/drm_gem_dma_helper.c:1 drivers/gpu/drm/drm_gem_shmem_helper.c:1 drivers/gpu/drm/drm_gem_ttm_helper.c:1 drivers/gpu/drm/drm_gem_vram_helper.c:5 drivers/gpu/drm/drm_lease.c:6 drivers/gpu/drm/drm_mipi_dbi.c:3 drivers/gpu/drm/drm_mode_config.c:4 drivers/gpu/drm/drm_mode_object.c:20 drivers/gpu/drm/drm_modeset_helper.c:1 drivers/gpu/drm/drm_modeset_lock.c:1 drivers/gpu/drm/drm_of.c:3 drivers/gpu/drm/drm_plane.c:35 drivers/gpu/drm/drm_plane_helper.c:2 drivers/gpu/drm/drm_prime.c:9 drivers/gpu/drm/drm_probe_helper.c:3 drivers/gpu/drm/drm_property.c:11 drivers/gpu/drm/drm_simple_kms_helper.c:4 drivers/gpu/drm/drm_syncobj.c:26 but maybe not worth the churn for what is already there for a long time? This originally dates back to around or slightly after when the drm code was a set of template headers with the objective of sharing code with some bsds, and then I guess it also leaked. The reason I sent this patch was I made a review comment of this for drm_gpuvm and then also promised to send a patch against drm_exec. Personally, I think the one time churn is worth it to unify and keep the codebase in kernel types only. This is basically what we did in i915 years ago, and new c99 types don't really even creep in because there are zero examples around. It's natural to follow the style around you instead of mixing. +1. /Thomas BR, Jani.
[PATCH 0/3] LVDS Controller Support for SAM9X7 SoC
This patch series introduces LVDS controller support for the SAM9X7 SoC. The LVDS controller is designed to work with Microchip's sam9x7 series System-on-Chip (SoC) devices, providing Low Voltage Differential Signaling capabilities. Dharma Balasubiramani (3): dt-bindings: display: bridge: add sam9x7-lvds compatible drm/bridge: add lvds controller support for sam9x7 MAINTAINERS: add SAM9X7 SoC's LVDS controller .../display/bridge/microchip,sam9x7-lvds.yaml | 59 + MAINTAINERS | 8 + drivers/gpu/drm/bridge/Kconfig| 7 + drivers/gpu/drm/bridge/Makefile | 1 + drivers/gpu/drm/bridge/microchip-lvds.c | 250 ++ 5 files changed, 325 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/microchip,sam9x7-lvds.yaml create mode 100644 drivers/gpu/drm/bridge/microchip-lvds.c -- 2.25.1
[PATCH 1/3] dt-bindings: display: bridge: add sam9x7-lvds compatible
Add the 'sam9x7-lvds' compatible binding, which describes the Low Voltage Differential Signaling (LVDS) Controller found on Microchip's sam9x7 series System-on-Chip (SoC) devices. This binding will be used to define the properties and configuration for the LVDS Controller in DT. Signed-off-by: Dharma Balasubiramani --- .../display/bridge/microchip,sam9x7-lvds.yaml | 59 +++ 1 file changed, 59 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/microchip,sam9x7-lvds.yaml diff --git a/Documentation/devicetree/bindings/display/bridge/microchip,sam9x7-lvds.yaml b/Documentation/devicetree/bindings/display/bridge/microchip,sam9x7-lvds.yaml new file mode 100644 index ..8c2c5b858c85 --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/microchip,sam9x7-lvds.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/bridge/microchip,sam9x7-lvds.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Microchip SAM9X7 LVDS Controller + +maintainers: + - Dharma Balasubiramani + +description: | + The Low Voltage Differential Signaling Controller (LVDSC) manages data + format conversion from the LCD Controller internal DPI bus to OpenLDI + LVDS output signals. LVDSC functions include bit mapping, balanced mode + management, and serializer. + +properties: + compatible: +const: microchip,sam9x7-lvds + + reg: +maxItems: 1 + + interrupts: +maxItems: 1 + + clocks: +items: + - description: Peripheral Bus Clock + + clock-names: +items: + - const: pclk + - const: gclk +minItems: 1 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + +additionalProperties: false + +examples: + - | +#include +#include +#include + +lvds-controller@f806 { + compatible = "microchip,sam9x7-lvds"; + reg = <0xf806 0x100>; + interrupts = <56 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 56>; + clock-names = "pclk"; +}; -- 2.25.1
[PATCH 2/3] drm/bridge: add lvds controller support for sam9x7
Add a new LVDS controller driver for sam9x7 which does the following: - Prepares and enables the LVDS Peripheral clock - Defines its connector type as DRM_MODE_CONNECTOR_LVDS and adds itself to the global bridge list. - Identifies its output endpoint as panel and adds it to the encoder display pipeline - Enables the LVDS serializer Signed-off-by: Manikandan Muralidharan Signed-off-by: Dharma Balasubiramani --- drivers/gpu/drm/bridge/Kconfig | 7 + drivers/gpu/drm/bridge/Makefile | 1 + drivers/gpu/drm/bridge/microchip-lvds.c | 250 3 files changed, 258 insertions(+) create mode 100644 drivers/gpu/drm/bridge/microchip-lvds.c diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index 3e6a4e2044c0..200afb36e421 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -173,6 +173,13 @@ config DRM_MEGACHIPS_STDP_GE_B850V3_FW to DP++. This is used with the i.MX6 imx-ldb driver. You are likely to say N here. +config DRM_MICROCHIP_LVDS_SERIALIZER + tristate "Microchip LVDS serailzer support" + depends on OF + depends on DRM_ATMEL_HLCDC + help + Support for Microchip's LVDS serializer. + config DRM_NWL_MIPI_DSI tristate "Northwest Logic MIPI DSI Host controller" depends on DRM diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index 2b892b7ed59e..e3804e93d324 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_DRM_LONTIUM_LT9611) += lontium-lt9611.o obj-$(CONFIG_DRM_LONTIUM_LT9611UXC) += lontium-lt9611uxc.o obj-$(CONFIG_DRM_LVDS_CODEC) += lvds-codec.o obj-$(CONFIG_DRM_MEGACHIPS_STDP_GE_B850V3_FW) += megachips-stdp-ge-b850v3-fw.o +obj-$(CONFIG_DRM_MICROCHIP_LVDS_SERIALIZER) += microchip-lvds.o obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o obj-$(CONFIG_DRM_PARADE_PS8640) += parade-ps8640.o diff --git a/drivers/gpu/drm/bridge/microchip-lvds.c b/drivers/gpu/drm/bridge/microchip-lvds.c new file mode 100644 index ..297f5ae514f6 --- /dev/null +++ b/drivers/gpu/drm/bridge/microchip-lvds.c @@ -0,0 +1,250 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2023 Microchip Technology Inc. and its subsidiaries + * + * Author: Manikandan Muralidharan + * Author: Dharma Balasubiramani + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define LVDS_POLL_TIMEOUT_MS 1000 + +/* LVDSC register offsets */ +#define LVDSC_CR 0x00 +#define LVDSC_CFGR 0x04 +#define LVDSC_SR 0x0C +#define LVDSC_WPMR 0xE4 + +/* Bitfields in LVDSC_CR (Control Register) */ +#define LVDSC_CR_SER_ENBIT(0) + +/* Bitfields in LVDSC_CFGR (Configuration Register) */ +#define LVDSC_CFGR_PIXSIZE_24BITS 0 +#define LVDSC_CFGR_DEN_POL_HIGH0 +#define LVDSC_CFGR_DC_UNBALANCED 0 +#define LVDSC_CFGR_MAPPING_JEIDA BIT(6) + +/*Bitfields in LVDSC_SR */ +#define LVDSC_SR_CSBIT(0) + +/* Bitfields in LVDSC_WPMR (Write Protection Mode Register) */ +#define LVDSC_WPMR_WPKEY_MASK GENMASK(31, 8) +#define LVDSC_WPMR_WPKEY_PSSWD 0x4C5644 + +struct mchp_lvds { + struct device *dev; + void __iomem *regs; + struct clk *pclk; + int format; /* vesa or jeida format */ + struct drm_panel *panel; + struct drm_bridge bridge; + struct drm_bridge *panel_bridge; +}; + +static inline struct mchp_lvds *bridge_to_lvds(struct drm_bridge *bridge) +{ + return container_of(bridge, struct mchp_lvds, bridge); +} + +static inline u32 lvds_readl(struct mchp_lvds *lvds, u32 offset) +{ + return readl_relaxed(lvds->regs + offset); +} + +static inline void lvds_writel(struct mchp_lvds *lvds, u32 offset, u32 val) +{ + writel_relaxed(val, lvds->regs + offset); +} + +static void lvds_serialiser_on(struct mchp_lvds *lvds) +{ + unsigned long timeout = jiffies + msecs_to_jiffies(LVDS_POLL_TIMEOUT_MS); + + /* The LVDSC registers can only be written if WPEN is cleared */ + lvds_writel(lvds, LVDSC_WPMR, (LVDSC_WPMR_WPKEY_PSSWD & + LVDSC_WPMR_WPKEY_MASK)); + + /* Wait for the status of configuration registers to be changed */ + while (lvds_readl(lvds, LVDSC_SR) & LVDSC_SR_CS) { + if (time_after(jiffies, timeout)) { + dev_err(lvds->dev, "%s: timeout error\n", __func__); + return; + } + usleep_range(1000, 2000); + } + + /* Configure the LVDSC */ + lvds_writel(lvds, LVDSC_CFGR, (LVDSC_CFGR_MAPPING_JEIDA | + LVDSC_CFGR_DC_UNBALANCED | + LVDSC_CFGR_DEN_PO
[PATCH 3/3] MAINTAINERS: add SAM9X7 SoC's LVDS controller
Add the newly added LVDS controller for the SAM9X7 SoC to the existing MAINTAINERS entry. Signed-off-by: Dharma Balasubiramani --- MAINTAINERS | 8 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index a7c4cf8201e0..24a266d20df6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14230,6 +14230,14 @@ S: Supported F: Documentation/devicetree/bindings/power/reset/atmel,sama5d2-shdwc.yaml F: drivers/power/reset/at91-sama5d2_shdwc.c +MICROCHIP SAM9x7-COMPATIBLE LVDS CONTROLLER +M: Manikandan Muralidharan +M: Dharma Balasubiramani +L: dri-devel@lists.freedesktop.org +S: Supported +F: Documentation/devicetree/bindings/display/bridge/microchip,sam9x7-lvds.yaml +F: drivers/gpu/drm/bridge/microchip-lvds.c + MICROCHIP SOC DRIVERS M: Conor Dooley S: Supported -- 2.25.1
Re: BUG [RESEND]: kernel NULL pointer dereference, address: 0000000000000008
Perhaps similar to the problem I encountered earlier, you can try the following patch https://lists.freedesktop.org/archives/amd-gfx/2024-January/103259.html Regards, Ma Jun On 1/21/2024 3:54 AM, Mirsad Todorovac wrote: > Hi, > > The last email did not pass to the most of the recipients due to banned .xz > attachment. > > As the .config is too big to send inline or uncompressed either, I will omit > it in this > attempt. In the meantime, I had some success in decoding the stack trace, but > sadly not > complete. > > I don't think this Oops is deterministic, but I am working on a reproducer. > > The platform is Ubuntu 22.04 LTS. > > Complete list of hardware and .config is available here: > > https://domac.alu.unizg.hr/~mtodorov/linux/bugreports/amdgpu/6.7.0-rtl-v0.2-nokcsan-09928-g052d534373b7/ > > Best regards, > Mirsad > > --- > kernel: [5.576702] BUG: kernel NULL pointer dereference, address: > 0008 > kernel: [5.576707] #PF: supervisor read access in kernel mode > kernel: [5.576710] #PF: error_code(0x) - not-present page > kernel: [5.576712] PGD 0 P4D 0 > kernel: [5.576715] Oops: [#1] PREEMPT SMP NOPTI > kernel: [5.576718] CPU: 9 PID: 650 Comm: systemd-udevd Not tainted > 6.7.0-rtl-v0.2-nokcsan-09928-g052d534373b7 #2 > kernel: [5.576723] Hardware name: ASRock X670E PG Lightning/X670E PG > Lightning, BIOS 1.21 04/26/2023 > kernel: [5.576726] RIP: 0010:gfx_v10_0_early_init > (drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:4009 > drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:7478) amdgpu > kernel: [ 5.576872] Code: 8d 55 a8 4c 89 ff e8 e4 83 ec ff 41 89 c2 83 f8 ed > 0f 84 b3 fd ff ff 85 c0 74 05 0f 1f 44 00 00 49 8b 87 08 87 01 00 4c 89 ff > <48> 8b 40 08 0f b7 50 0a 0f b7 70 08 e8 e4 42 fb ff 41 89 c2 85 c0 > All code > > 0:8d 55 a8lea-0x58(%rbp),%edx > 3:4c 89 ffmov%r15,%rdi > 6:e8 e4 83 ec ff call 0xffec83ef > b:41 89 c2mov%eax,%r10d > e:83 f8 edcmp$0xffed,%eax >11:0f 84 b3 fd ff ff je 0xfdca >17:85 c0 test %eax,%eax >19:74 05 je 0x20 >1b:0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) >20:49 8b 87 08 87 01 00mov0x18708(%r15),%rax >27:4c 89 ffmov%r15,%rdi >2a:* 48 8b 40 08 mov0x8(%rax),%rax <-- > trapping instruction >2e:0f b7 50 0a movzwl 0xa(%rax),%edx >32:0f b7 70 08 movzwl 0x8(%rax),%esi >36:e8 e4 42 fb ff call 0xfffb431f >3b:41 89 c2mov%eax,%r10d >3e:85 c0 test %eax,%eax > > Code starting with the faulting instruction > === > 0:48 8b 40 08 mov0x8(%rax),%rax > 4:0f b7 50 0a movzwl 0xa(%rax),%edx > 8:0f b7 70 08 movzwl 0x8(%rax),%esi > c:e8 e4 42 fb ff call 0xfffb42f5 >11:41 89 c2mov%eax,%r10d >14:85 c0 test %eax,%eax > kernel: [5.576878] RSP: 0018:a5b3c103f720 EFLAGS: 00010282 > kernel: [5.576881] RAX: RBX: c1d73489 RCX: > > kernel: [5.576884] RDX: RSI: RDI: > 91ae4fa8 > kernel: [5.576886] RBP: a5b3c103f7b0 R08: R09: > > kernel: [5.576889] R10: ffea R11: R12: > 91ae4fa986e8 > kernel: [5.576892] R13: 91ae4fa986d8 R14: 91ae4fa986f8 R15: > 91ae4fa8 > kernel: [5.576895] FS: 7fdaa343c8c0() GS:91bd5844() > knlGS: > kernel: [5.576898] CS: 0010 DS: ES: CR0: 80050033 > kernel: [5.576900] CR2: 0008 CR3: 0001222d CR4: > 00750ef0 > kernel: [5.576903] PKRU: 5554 > kernel: [5.576905] Call Trace: > kernel: [5.576907] > kernel: [5.576909] ? show_regs (arch/x86/kernel/dumpstack.c:479) > kernel: [5.576914] ? __die (arch/x86/kernel/dumpstack.c:421 > arch/x86/kernel/dumpstack.c:434) > kernel: [5.576917] ? page_fault_oops (arch/x86/mm/fault.c:707) > kernel: [5.576921] ? srso_alias_return_thunk > (arch/x86/lib/retpoline.S:181) > kernel: [5.576925] ? crypto_alloc_tfmmem.isra.0 (crypto/api.c:497) > kernel: [5.576930] ? do_user_addr_fault (arch/x86/mm/fault.c:1264) > kernel: [5.576934] ? exc_page_fault > (./arch/x86/include/asm/paravirt.h:693 arch/x86/mm/fault.c:1515 > arch/x86/mm/fault.c:1563) > kernel: [5.576937]
Re: [PATCH 2/8] dt-bindings: dsi-controller-main: Document missing msm8976 compatible
On 21/01/2024 20:41, Adam Skladowski wrote: > When all dsi-ctrl compats were added msm8976 was missed, include it too. > > Signed-off-by: Adam Skladowski > --- Reviewed-by: Krzysztof Kozlowski Best regards, Krzysztof
Re: [PATCH 3/8] dt-bindings: msm: qcom,mdss: Include ommited fam-b compatible
On 21/01/2024 20:41, Adam Skladowski wrote: > During conversion 28nm-hpm-fam-b compat got lost, add it. Please add Fixes tag and put this commit as first in your patchset or even as separate one. Best regards, Krzysztof
Re: [PATCH 5/8] dt-bindings: drm/msm/gpu: Document AON clock for A506/A510
On 21/01/2024 20:41, Adam Skladowski wrote: > Adreno 506(MSM8953) and Adreno 510(MSM8976) require > Always-on branch clock to be enabled, describe it. > > Signed-off-by: Adam Skladowski > --- > Documentation/devicetree/bindings/display/msm/gpu.yaml | 6 -- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/Documentation/devicetree/bindings/display/msm/gpu.yaml > b/Documentation/devicetree/bindings/display/msm/gpu.yaml > index b019db954793..9e36f54a5caf 100644 > --- a/Documentation/devicetree/bindings/display/msm/gpu.yaml > +++ b/Documentation/devicetree/bindings/display/msm/gpu.yaml > @@ -133,7 +133,7 @@ allOf: >properties: > clocks: >minItems: 2 > - maxItems: 7 > + maxItems: 8 I would prefer we start enforcing the order. The initial flexibility was because of conversion from the old bindings and dealing with some technical debt, AFAIU. This is requirement of new clock, so maybe better add dedicated if:then case which will be enforcing the order with always-on at the end. Best regards, Krzysztof
Re: [PATCH v3 3/3] dt-bindings: mfd: atmel,hlcdc: Convert to DT schema format
On Mon, Jan 22, 2024 at 03:38:41AM +, dharm...@microchip.com wrote: > Hi Conor, > On 19/01/24 5:33 pm, Conor Dooley - M52691 wrote: > > On Fri, Jan 19, 2024 at 03:32:49AM +, dharm...@microchip.com wrote: > >> On 18/01/24 9:10 pm, Conor Dooley wrote: > >>> On Thu, Jan 18, 2024 at 02:56:12PM +0530, Dharma Balasubiramani wrote: > Convert the atmel,hlcdc binding to DT schema format. > > Adjust the clock-names property to clarify that the LCD controller > expects > one of these clocks (either sys_clk or lvds_pll_clk to be present but not > both) along with the slow_clk and periph_clk. This alignment with the > actual > hardware requirements will enable accurate device tree configuration for > systems using the HLCDC IP. > > Signed-off-by: Dharma Balasubiramani > --- > changelog > v2 -> v3 > - Rename hlcdc-display-controller and hlcdc-pwm to generic names. > - Modify the description by removing the unwanted comments and '|'. > - Modify clock-names simpler. > v1 -> v2 > - Remove the explicit copyrights. > - Modify title (not include words like binding/driver). > - Modify description actually describing the hardware and not the driver. > - Add details of lvds_pll addition in commit message. > - Ref endpoint and not endpoint-base. > - Fix coding style. > ... > .../devicetree/bindings/mfd/atmel,hlcdc.yaml | 97 +++ > .../devicetree/bindings/mfd/atmel-hlcdc.txt | 56 --- > 2 files changed, 97 insertions(+), 56 deletions(-) > create mode 100644 > Documentation/devicetree/bindings/mfd/atmel,hlcdc.yaml > delete mode 100644 > Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt > > diff --git a/Documentation/devicetree/bindings/mfd/atmel,hlcdc.yaml > b/Documentation/devicetree/bindings/mfd/atmel,hlcdc.yaml > new file mode 100644 > index ..eccc998ac42c > --- /dev/null > +++ b/Documentation/devicetree/bindings/mfd/atmel,hlcdc.yaml > @@ -0,0 +1,97 @@ > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id:http://devicetree.org/schemas/mfd/atmel,hlcdc.yaml# > +$schema:http://devicetree.org/meta-schemas/core.yaml# > + > +title: Atmel's HLCD Controller > + > +maintainers: > + - Nicolas Ferre > + - Alexandre Belloni > + - Claudiu Beznea > + > +description: > + The Atmel HLCDC (HLCD Controller) IP available on Atmel SoCs exposes > two > + subdevices, a PWM chip and a Display Controller. > + > +properties: > + compatible: > +enum: > + - atmel,at91sam9n12-hlcdc > + - atmel,at91sam9x5-hlcdc > + - atmel,sama5d2-hlcdc > + - atmel,sama5d3-hlcdc > + - atmel,sama5d4-hlcdc > + - microchip,sam9x60-hlcdc > + - microchip,sam9x75-xlcdc > + > + reg: > +maxItems: 1 > + > + interrupts: > +maxItems: 1 > + > + clocks: > +maxItems: 3 > >>> Hmm, one thing I probably should have said on the previous version, but > >>> I missed somehow: It would be good to add an items list to the clocks > >>> property here to explain what the 3 clocks are/are used for - especially > >>> since there is additional complexity being added here to use either the > >>> sys or lvds clocks. > >> May I inquire if this approach is likely to be effective? > >> > >> clocks: > >> items: > >> - description: peripheral clock > >> - description: generic clock or lvds pll clock > >> Once the LVDS PLL is enabled, the pixel clock is used as the > >> clock for LCDC, so its GCLK is no longer needed. > >> - description: slow clock > >> maxItems: 3 > > > > Hmm that sounds very suspect to me. "Once the lvdspll is enabled the > > generic clock is no longer needed" sounds like both clocks can be provided > > to the IP on different pins and their provision is not mutually > > exclusive, just that the IP will only actually use one at a time. If > > that is the case, then this patch is nott correct and the binding should > > allow for 4 clocks, with both the generic clock and the lvds pll being > > present in the DT at the same time. > > > > I vaguely recall internal discussion about this problem some time back > > but the details all escape me. > > Let's delve deeper into the clock configuration for LCDC_PCK. > > Considering the flexibility of the design, it appears that both clocks, > sys_clk (generic clock) and lvds_pll_clk, can indeed be provided to the > IP simultaneously. The crucial aspect, however, is that the IP will > utilize only one of these clocks at any given time. This aligns with the > specific requirements of the application, where the choice of clock > depends on whether the L
Re: [PATCH] mm: Remove double faults once write a device pfn
Am 22.01.24 um 04:32 schrieb Xianrong Zhou: The vmf_insert_pfn_prot could cause unnecessary double faults on a device pfn. Because currently the vmf_insert_pfn_prot does not make the pfn writable so the pte entry is normally read-only or dirty catching. What? How do you got to this conclusion? The first fault only sets up the pte entry which actually is dirty catching. And the second immediate fault to the pfn due to first dirty catching when the cpu re-execute the store instruction. It could be that this is done to work around some hw behavior, but not because of dirty catching. Normally if the drivers call vmf_insert_pfn_prot and also supply 'pfn_mkwrite' callback within vm_operations_struct which requires the pte to be dirty catching then the vmf_insert_pfn_prot and the double fault are reasonable. It is not a problem. Well, as far as I can see that behavior absolutely doesn't make sense. When pfn_mkwrite is requested then the driver should use PAGE_COPY, which is exactly what VMWGFX (the only driver using dirty tracking) is doing. Everybody else uses PAGE_SHARED which should make the pte writeable immediately. Regards, Christian. However the most of drivers calling vmf_insert_pfn_prot do not supply the 'pfn_mkwrite' callback so that the second fault is unnecessary. So just like vmf_insert_mixed and vmf_insert_mixed_mkwrite pair, we should also supply vmf_insert_pfn_mkwrite for drivers as well. Signed-off-by: Xianrong Zhou --- arch/x86/entry/vdso/vma.c | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c| 2 +- drivers/gpu/drm/i915/gem/i915_gem_ttm.c| 2 +- drivers/gpu/drm/nouveau/nouveau_gem.c | 2 +- drivers/gpu/drm/radeon/radeon_gem.c| 2 +- drivers/gpu/drm/ttm/ttm_bo_vm.c| 8 +--- drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c | 8 +--- include/drm/ttm/ttm_bo.h | 3 ++- include/linux/mm.h | 2 +- mm/memory.c| 14 +++--- 10 files changed, 30 insertions(+), 16 deletions(-) diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c index 7645730dc228..dd2431c2975f 100644 --- a/arch/x86/entry/vdso/vma.c +++ b/arch/x86/entry/vdso/vma.c @@ -185,7 +185,8 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm, if (pvti && vclock_was_used(VDSO_CLOCKMODE_PVCLOCK)) { return vmf_insert_pfn_prot(vma, vmf->address, __pa(pvti) >> PAGE_SHIFT, - pgprot_decrypted(vma->vm_page_prot)); + pgprot_decrypted(vma->vm_page_prot), + true); } } else if (sym_offset == image->sym_hvclock_page) { pfn = hv_get_tsc_pfn(); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 49a5f1c73b3e..adcb20d9e624 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -64,7 +64,7 @@ static vm_fault_t amdgpu_gem_fault(struct vm_fault *vmf) } ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot, - TTM_BO_VM_NUM_PREFAULT); + TTM_BO_VM_NUM_PREFAULT, true); drm_dev_exit(idx); } else { diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index 9227f8146a58..c6f13ae6c308 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -1114,7 +1114,7 @@ static vm_fault_t vm_fault_ttm(struct vm_fault *vmf) if (drm_dev_enter(dev, &idx)) { ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot, - TTM_BO_VM_NUM_PREFAULT); + TTM_BO_VM_NUM_PREFAULT, true); drm_dev_exit(idx); } else { ret = ttm_bo_vm_dummy_page(vmf, vmf->vma->vm_page_prot); diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 49c2bcbef129..7e1453762ec9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -56,7 +56,7 @@ static vm_fault_t nouveau_ttm_fault(struct vm_fault *vmf) nouveau_bo_del_io_reserve_lru(bo); prot = vm_get_page_prot(vma->vm_flags); - ret = ttm_bo_vm_fault_reserved(vmf, prot, TTM_BO_VM_NUM_PREFAULT); + ret = ttm_bo_vm_fault_reserved(vmf, prot, TTM_BO_VM_NUM_PREFAULT, true); nouveau_bo_add_io_reserve_lru(bo); if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) return ret; diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 3fec3acdaf28..b21cf00ae162 100644 --- a/drivers/gpu/drm/rade
Re: [PATCH v2 0/9] accel/ivpu fixes for 6.8
Applied to drm-misc-fixes On 15.01.2024 14:44, Jacek Lawrynowicz wrote: > Various driver fixes: > - Fixes for infinite loops, missing locks and DMA-API debug warnings > - Deprecate DRM_IVPU_PARAM_CONTEXT_PRIORITY > - Improve diagnostic messages > > v2 includes changes from v1 review comments and drops IRQ infinite loop patch. > > Jacek Lawrynowicz (4): > accel/ivpu: Fix for missing lock around drm_gem_shmem_vmap() > accel/ivpu: Free buffer sgt on unbind > accel/ivpu: Disable buffer sharing among VPU contexts > accel/ivpu: Improve buffer object debug logs > > Wachowski, Karol (5): > accel/ivpu: Dump MMU events in case of VPU boot timeout > accel/ivpu: Call diagnose failure in ivpu_mmu_cmdq_sync() > accel/ivpu: Add debug prints for MMU map/unmap operations > accel/ivpu: Add diagnostic messages when VPU fails to boot or suspend > accel/ivpu: Deprecate DRM_IVPU_PARAM_CONTEXT_PRIORITY param > > drivers/accel/ivpu/ivpu_drv.c | 17 +--- > drivers/accel/ivpu/ivpu_drv.h | 2 +- > drivers/accel/ivpu/ivpu_gem.c | 126 +- > drivers/accel/ivpu/ivpu_gem.h | 1 - > drivers/accel/ivpu/ivpu_job.c | 3 + > drivers/accel/ivpu/ivpu_mmu.c | 10 ++ > drivers/accel/ivpu/ivpu_mmu.h | 1 + > drivers/accel/ivpu/ivpu_mmu_context.c | 9 ++ > drivers/accel/ivpu/ivpu_pm.c | 4 +- > include/uapi/drm/ivpu_accel.h | 25 - > 10 files changed, 96 insertions(+), 102 deletions(-) > > -- > 2.43.0
[Bug 198551] amdgpu error on shutdown or gpu intense game
https://bugzilla.kernel.org/show_bug.cgi?id=198551 Artem S. Tashkinov (a...@gmx.com) changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |OBSOLETE --- Comment #7 from Artem S. Tashkinov (a...@gmx.com) --- If you still experience this under 6.6.13 or 6.7.1 please file a bug report here: https://gitlab.freedesktop.org/drm/amd/-/issues -- You may reply to this email to add a comment. You are receiving this mail because: You are watching the assignee of the bug.
Re: [PATCH v3 1/3] leds: ktd2692: move ExpressWire code to library
On Sat, Jan 20, 2024 at 10:26:43PM +0100, Duje Mihanović wrote: > The ExpressWire protocol is shared between at least KTD2692 and KTD2801 > with slight differences such as timings and the former not having a > defined set of pulses for enabling the protocol (possibly because it > does not support PWM unlike KTD2801). Despite these differences the > ExpressWire handling code can be shared between the two, so move it into > a library in preparation for adding KTD2801 support. > > Suggested-by: Daniel Thompson > Signed-off-by: Duje Mihanović > --- > MAINTAINERS | 7 +++ > drivers/leds/Kconfig | 3 ++ > drivers/leds/Makefile | 3 ++ > drivers/leds/flash/Kconfig| 1 + > drivers/leds/flash/leds-ktd2692.c | 91 > +++ > drivers/leds/leds-expresswire.c | 59 + > include/linux/leds-expresswire.h | 35 +++ > 7 files changed, 132 insertions(+), 67 deletions(-) > > diff --git a/MAINTAINERS b/MAINTAINERS > index a7c4cf8201e0..87b12d2448a0 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -7902,6 +7902,13 @@ S: Maintained > T: git git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat.git > F: fs/exfat/ > > +EXPRESSWIRE PROTOCOL LIBRARY > +M: Duje Mihanović > +L: linux-l...@vger.kernel.org > +S: Maintained > +F: drivers/leds/leds-expresswire.c > +F: include/linux/leds-expresswire.h > + > EXT2 FILE SYSTEM > M: Jan Kara > L: linux-e...@vger.kernel.org > diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig > index 6292fddcc55c..d29b6823e7d1 100644 > --- a/drivers/leds/Kconfig > +++ b/drivers/leds/Kconfig > @@ -181,6 +181,9 @@ config LEDS_EL15203000 > To compile this driver as a module, choose M here: the module > will be called leds-el15203000. > > +config LEDS_EXPRESSWIRE > + bool > + Shouldn't there be a "select GPIOLIB" here? It seems odd to make the clients responsible for the dependencies. BTW there seems to be very little consistency across the kernel between "depends on GPIOLIB" and "select GPIOLIB".. but select is marginally more popular (283 vs. 219 in the kernel I checked). > diff --git a/drivers/leds/flash/leds-ktd2692.c > b/drivers/leds/flash/leds-ktd2692.c > index 598eee5daa52..8c17de3d621f 100644 > --- a/drivers/leds/flash/leds-ktd2692.c > +++ b/drivers/leds/flash/leds-ktd2692.c > > static void ktd2692_expresswire_write(struct ktd2692_context *led, u8 value) > { > int i; > > - ktd2692_expresswire_start(led); > + expresswire_start(&led->props); > for (i = 7; i >= 0; i--) > - ktd2692_expresswire_set_bit(led, value & BIT(i)); > - ktd2692_expresswire_end(led); > + expresswire_set_bit(&led->props, value & BIT(i)); > + expresswire_end(&led->props); > } Is there any reason not to have an expresswire_write_u8() method in the library code? It is a concept that appears in both drivers. Daniel.
Re: [BUG][BISECTED] Freeze at loading init ramdisk
On Thu, Jan 18, 2024 at 09:04:05PM +0100, Mirsad Todorovac wrote: > > > On 1/18/24 08:45, Uwe Kleine-König wrote: > > Hello Mirsad, > > > > On Wed, Jan 17, 2024 at 07:47:49PM +0100, Mirsad Todorovac wrote: > > > On 1/16/24 01:32, Mirsad Todorovac wrote: > > > > On the Ubuntu 22.04 LTS Jammy platform, on a mainline vanilla torvalds > > > > tree kernel, the boot > > > > freezes upon first two lines and before any systemd messages. > > > > > > > > (Please find the config attached.) > > > > > > > > Bisecting the bug led to this result: > > > > > > > > marvin@defiant:~/linux/kernel/linux_torvalds$ git bisect good > > > > d97a78423c33f68ca6543de510a409167baed6f5 is the first bad commit > > > > commit d97a78423c33f68ca6543de510a409167baed6f5 > > > > Merge: 61da593f4458 689237ab37c5 > > > > Author: Linus Torvalds > > > > Date: Fri Jan 12 14:38:08 2024 -0800 > > > > > > > > [...] > > > > > > > > Hope this helps. > > > > > > P.S. > > > > > > As I see that this is a larger merge commit, with 5K+ lines changed, I > > > don't think I can > > > bisect further to determine the culprit. > > > > Actually it's not that hard. If a merge commit is the first bad commit > > for a bisection, either the merge wasn't done correctly (less likely, > > looking at d97a78423c33f68ca6543de510a409167baed6f5 I'd bet this isn't > > the problem); or changes on different sides conflict or you did > > something wrong during bisection. > > > > To rule out the third option, you can just retest d97a78423c33, > > 61da593f4458 and 689237ab37c5. If d97a78423c33 is the only bad one, you > > did it right. > > This was confirmed. > > > Then to further debug the second option you can find out the offending > > commit on each side with a bisection as follows, here for the RHS (i.e. > > 689237ab37c5): > > > > git bisect start 689237ab37c5 $(git merge-base 61da593f4458 > > 689237ab37c5) > > > > and then in each bisection step do: > > > > git merge --no-commit 61da593f4458 > > test if the problem is present > > git reset --hard > > git bisect good/bad > > > > In this case you get merge conflicts in drivers/video/fbdev/amba-clcd.c > > and drivers/video/fbdev/vermilion/vermilion.c. In the assumption that > > you don't have these enabled in your .config, you can just ignore these. > > > > Side note: A problem during bisection can be that the .config changes > > along the process. You should put your config into (say) > > arch/x86/configs/lala_defconfig and do > > > > make lala_defconfig > > > > before building each step to prevent this. > > I must have done something wrong: > > marvin@defiant:~/linux/kernel/linux_torvalds$ git bisect log > # bad: [689237ab37c59b9909bc9371d7fece3081683fba] fbdev/intelfb: Remove driver > # good: [de927f6c0b07d9e698416c5b287c521b07694cac] Merge tag 's390-6.8-1' of > git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux > git bisect start '689237ab37c5' 'de927f6c0b07d9e698416c5b287c521b07694cac' > # good: [d9f25b59ed85ae45801cf45fe17eb269b0ef3038] fbdev: Remove support for > Carillo Ranch driver > git bisect good d9f25b59ed85ae45801cf45fe17eb269b0ef3038 > # good: [e2e0b838a1849f92612a8305c09aaf31bf824350] video/sticore: Remove info > field from STI struct > git bisect good e2e0b838a1849f92612a8305c09aaf31bf824350 > # good: [778e73d2411abc8f3a2d60dbf038acaec218792e] drm/hyperv: Remove > firmware framebuffers with aperture helper > git bisect good 778e73d2411abc8f3a2d60dbf038acaec218792e > # good: [df67699c9cb0ceb70f6cc60630ca938c06773eda] firmware/sysfb: Clear > screen_info state after consuming it > git bisect good df67699c9cb0ceb70f6cc60630ca938c06773eda FTR: Now that you identified df67699c9cb0ce as the culprit, calling git bisect good on it was wrong, so something was fishy in your testing and it's no surprise the bisection found a wrong result. Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-König| Industrial Linux Solutions | https://www.pengutronix.de/ | signature.asc Description: PGP signature
Re: [PATCH v3 3/3] backlight: Add Kinetic KTD2801 backlight support
On Sat, Jan 20, 2024 at 10:26:45PM +0100, Duje Mihanović wrote: > KTD2801 is a LED backlight driver IC found in samsung,coreprimevelte. > The brightness can be set using PWM or the ExpressWire protocol. Add > support for the KTD2801. > > Signed-off-by: Duje Mihanović As Linus W. said, this is looking really nice now. Thanks! Just a couple of nits below. > diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig > index 51387b1ef012..585a5a713759 100644 > --- a/drivers/video/backlight/Kconfig > +++ b/drivers/video/backlight/Kconfig > @@ -183,6 +183,14 @@ config BACKLIGHT_KTD253 > which is a 1-wire GPIO-controlled backlight found in some mobile > phones. > > +config BACKLIGHT_KTD2801 > + tristate "Backlight Driver for Kinetic KTD2801" > + depends on GPIOLIB || COMPILE_TEST As patch 1 feedback, seems odd for the client to be responsible for this. It should be managed in LEDS_EXPRESSWIRE. > + select LEDS_EXPRESSWIRE > + help > + Say Y to enable the backlight driver for the Kinetic KTD2801 1-wire > + GPIO-controlled backlight found in Samsung Galaxy Core Prime VE LTE. > + > config BACKLIGHT_KTZ8866 > tristate "Backlight Driver for Kinetic KTZ8866" > depends on I2C > diff --git a/drivers/video/backlight/ktd2801-backlight.c > b/drivers/video/backlight/ktd2801-backlight.c > new file mode 100644 > index ..7b9d1a93aa71 > --- /dev/null > +++ b/drivers/video/backlight/ktd2801-backlight.c > @@ -0,0 +1,143 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Datasheet: > + * https://www.kinet-ic.com/uploads/web/KTD2801/KTD2801-04b.pdf > + */ > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/* These values have been extracted from Samsung's driver. */ > +#define KTD2801_EXPRESSWIRE_DETECT_DELAY_US 150 > +#define KTD2801_EXPRESSWIRE_DETECT_US270 > +#define KTD2801_SHORT_BITSET_US 5 > +#define KTD2801_LONG_BITSET_US (3 * > KTD2801_SHORT_BITSET_US) > +#define KTD2801_DATA_START_US5 > +#define KTD2801_END_OF_DATA_LOW_US 10 > +#define KTD2801_END_OF_DATA_HIGH_US 350 > +#define KTD2801_PWR_DOWN_DELAY_US2600 These are a little pointless now. They are all single use constants and have little documentary value. The lack of documentary value is because, for example, KTD2801_EXPRESSWIRE_DETECT_DELAY_US, is assigned to a structure field called detect_delay_us. Likewise I doubt that explicitly stating that long_bitset_us is 3x bigger than short_bitset_us is important for future driver maintainance. > + > +#define KTD2801_DEFAULT_BRIGHTNESS 100 > +#define KTD2801_MAX_BRIGHTNESS 255 > + > +const struct expresswire_timing ktd2801_timing = { > + .poweroff_us = KTD2801_PWR_DOWN_DELAY_US, > + .detect_delay_us = KTD2801_EXPRESSWIRE_DETECT_DELAY_US, > + .detect_us = KTD2801_EXPRESSWIRE_DETECT_US, > + .data_start_us = KTD2801_DATA_START_US, > + .short_bitset_us = KTD2801_SHORT_BITSET_US, > + .long_bitset_us = KTD2801_LONG_BITSET_US, > + .end_of_data_low_us = KTD2801_END_OF_DATA_LOW_US, > + .end_of_data_high_us = KTD2801_END_OF_DATA_HIGH_US > +}; > + > +struct ktd2801_backlight { > + struct expresswire_common_props props; > + struct backlight_device *bd; > + bool was_on; > +}; > + > +static int ktd2801_update_status(struct backlight_device *bd) > +{ > + struct ktd2801_backlight *ktd2801 = bl_get_data(bd); > + u8 brightness = (u8) backlight_get_brightness(bd); > + > + if (backlight_is_blank(bd)) { > + expresswire_power_off(&ktd2801->props); > + ktd2801->was_on = false; > + return 0; > + } > + > + if (!ktd2801->was_on) { > + expresswire_enable(&ktd2801->props); > + ktd2801->was_on = true; > + } > + > + expresswire_start(&ktd2801->props); > + > + for (int i = 7; i >= 0; i--) > + expresswire_set_bit(&ktd2801->props, !!(brightness & BIT(i))); The !! is redundant... but, as previous feedback, I think writing a u8 should be in the library code anyway. > + expresswire_end(&ktd2801->props); > + return 0; > +} > + > Daniel.
Re: [Linaro-mm-sig] [PATCH v5 1/6] dma-buf: Add dma_buf_{begin,end}_access()
Am 19.01.24 um 15:13 schrieb Paul Cercueil: These functions should be used by device drivers when they start and stop accessing the data of DMABUF. It allows DMABUF importers to cache the dma_buf_attachment while ensuring that the data they want to access is available for their device when the DMA transfers take place. As Daniel already noted as well this is a complete no-go from the DMA-buf design point of view. Regards, Christian. Signed-off-by: Paul Cercueil --- v5: New patch --- drivers/dma-buf/dma-buf.c | 66 +++ include/linux/dma-buf.h | 37 ++ 2 files changed, 103 insertions(+) diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 8fe5aa67b167..a8bab6c18fcd 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -830,6 +830,8 @@ static struct sg_table * __map_dma_buf(struct dma_buf_attachment *attach, * - dma_buf_mmap() * - dma_buf_begin_cpu_access() * - dma_buf_end_cpu_access() + * - dma_buf_begin_access() + * - dma_buf_end_access() * - dma_buf_map_attachment_unlocked() * - dma_buf_unmap_attachment_unlocked() * - dma_buf_vmap_unlocked() @@ -1602,6 +1604,70 @@ void dma_buf_vunmap_unlocked(struct dma_buf *dmabuf, struct iosys_map *map) } EXPORT_SYMBOL_NS_GPL(dma_buf_vunmap_unlocked, DMA_BUF); +/** + * @dma_buf_begin_access - Call before any hardware access from/to the DMABUF + * @attach:[in]attachment used for hardware access + * @sg_table: [in]scatterlist used for the DMA transfer + * @direction: [in]direction of DMA transfer + */ +int dma_buf_begin_access(struct dma_buf_attachment *attach, +struct sg_table *sgt, enum dma_data_direction dir) +{ + struct dma_buf *dmabuf; + bool cookie; + int ret; + + if (WARN_ON(!attach)) + return -EINVAL; + + dmabuf = attach->dmabuf; + + if (!dmabuf->ops->begin_access) + return 0; + + cookie = dma_fence_begin_signalling(); + ret = dmabuf->ops->begin_access(attach, sgt, dir); + dma_fence_end_signalling(cookie); + + if (WARN_ON_ONCE(ret)) + return ret; + + return 0; +} +EXPORT_SYMBOL_NS_GPL(dma_buf_begin_access, DMA_BUF); + +/** + * @dma_buf_end_access - Call after any hardware access from/to the DMABUF + * @attach:[in]attachment used for hardware access + * @sg_table: [in]scatterlist used for the DMA transfer + * @direction: [in]direction of DMA transfer + */ +int dma_buf_end_access(struct dma_buf_attachment *attach, + struct sg_table *sgt, enum dma_data_direction dir) +{ + struct dma_buf *dmabuf; + bool cookie; + int ret; + + if (WARN_ON(!attach)) + return -EINVAL; + + dmabuf = attach->dmabuf; + + if (!dmabuf->ops->end_access) + return 0; + + cookie = dma_fence_begin_signalling(); + ret = dmabuf->ops->end_access(attach, sgt, dir); + dma_fence_end_signalling(cookie); + + if (WARN_ON_ONCE(ret)) + return ret; + + return 0; +} +EXPORT_SYMBOL_NS_GPL(dma_buf_end_access, DMA_BUF); + #ifdef CONFIG_DEBUG_FS static int dma_buf_debug_show(struct seq_file *s, void *unused) { diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index 8ff4add71f88..8ba612c7cc16 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -246,6 +246,38 @@ struct dma_buf_ops { */ int (*end_cpu_access)(struct dma_buf *, enum dma_data_direction); + /** +* @begin_access: +* +* This is called from dma_buf_begin_access() when a device driver +* wants to access the data of the DMABUF. The exporter can use this +* to flush/sync the caches if needed. +* +* This callback is optional. +* +* Returns: +* +* 0 on success or a negative error code on failure. +*/ + int (*begin_access)(struct dma_buf_attachment *, struct sg_table *, + enum dma_data_direction); + + /** +* @end_access: +* +* This is called from dma_buf_end_access() when a device driver is +* done accessing the data of the DMABUF. The exporter can use this +* to flush/sync the caches if needed. +* +* This callback is optional. +* +* Returns: +* +* 0 on success or a negative error code on failure. +*/ + int (*end_access)(struct dma_buf_attachment *, struct sg_table *, + enum dma_data_direction); + /** * @mmap: * @@ -606,6 +638,11 @@ void dma_buf_detach(struct dma_buf *dmabuf, int dma_buf_pin(struct dma_buf_attachment *attach); void dma_buf_unpin(struct dma_buf_attachment *attach); +int dma_buf_begin_access(struct dma_buf_attachment *attach, +
Re: [PATCH v1 1/4] backlight: hx8357: Make use of device properties
On Sun, Jan 21, 2024 at 03:48:05PM +0200, Andy Shevchenko wrote: > On Mon, Jan 15, 2024 at 09:20:46AM +0100, Javier Martinez Canillas wrote: > > Andy Shevchenko writes: > > ... > > > > +typedef int (*hx8357_init)(struct lcd_device *); > > > > This kind of typedef usage is frowned upon in the Linux coding style [0] > > (per my understanding at least) and indeed in my opinion it makes harder > > to grep. > > > > [0] https://www.kernel.org/doc/Documentation/process/coding-style.rst > > Thanks for pointing this out. However, this piece does _not_ clarify typedef:s > for function pointers which I personally find a good to have. > > ... > > > > - ret = ((int (*)(struct lcd_device *))match->data)(lcdev); > > > > This is what I mean, before it was clear what was stored in match->data. > > But after you changes, what is returned by the device_get_match_data() > > function is opaque and you need to look at the typedef hx8357_init to > > figure that out. > > The above is so ugly in my opinion, that justifies using typedef:s even > if you are quite skeptical about them. FWIW I was pretty skeptical about it to. Largely because the three touchs (typedef, variable initialization, use) spread things around a bit too much. Can we at least name the type to make it obvious that it is a function pointer? Something like hx8357_init_fn . Daniel.
Re: [PATCH v3 1/3] dt-bindings: mailbox: Add mediatek,gce-props.yaml
Il 19/01/24 17:44, Conor Dooley ha scritto: Rob, On Fri, Jan 19, 2024 at 02:32:22PM +0800, Jason-JH.Lin wrote: Add mediatek,gce-props.yaml for common GCE properties that is used for both mailbox providers and consumers. We place the common property "mediatek,gce-events" in this binding currently. The property "mediatek,gce-events" is used for GCE event ID corresponding to a hardware event signal sent by the hardware or a sofware driver. If the mailbox providers or consumers want to manipulate the value of the event ID, they need to know the specific event ID. Signed-off-by: Jason-JH.Lin --- .../bindings/mailbox/mediatek,gce-props.yaml | 52 +++ Is bindings/mailbox the correct directory to put this in? Well, the GCE is a mailbox :-) ...but I get why you're asking... and I don't think that this should go to arm/mediatek/ as it's really just only referring to extra properties for kind of "special" mailbox client events... Cheers, Angelo 1 file changed, 52 insertions(+) create mode 100644 Documentation/devicetree/bindings/mailbox/mediatek,gce-props.yaml diff --git a/Documentation/devicetree/bindings/mailbox/mediatek,gce-props.yaml b/Documentation/devicetree/bindings/mailbox/mediatek,gce-props.yaml new file mode 100644 index ..68b519ff089f --- /dev/null +++ b/Documentation/devicetree/bindings/mailbox/mediatek,gce-props.yaml @@ -0,0 +1,52 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mailbox/mediatek,gce-props.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek Global Command Engine Common Propertes + +maintainers: + - Houlong Wei + +description: + The Global Command Engine (GCE) is an instruction based, multi-threaded, + single-core command dispatcher for MediaTek hardware. The Command Queue + (CMDQ) mailbox driver is a driver for GCE, implemented using the Linux + mailbox framework. It is used to receive messages from mailbox consumers + and configure GCE to execute the specified instruction set in the message. + We use mediatek,gce-mailbox.yaml to define the properties for CMDQ mailbox + driver. A device driver that uses the CMDQ driver to configure its hardware + registers is a mailbox consumer. The mailbox consumer can request a mailbox + channel corresponding to a GCE hardware thread to send a message, specifying + that the GCE thread to configure its hardware. The mailbox provider can also + reserved a mailbox channel to configure GCE hardware register by the spcific + GCE thread. This binding defines the common GCE properties for both mailbox + provider and consumers. + +properties: + mediatek,gce-events: +description: + GCE has an event table in SRAM, consisting of 1024 event IDs (0~1023). + Each event ID has a boolean event value with the default value 0. + The property mediatek,gce-events is used to obtain the event IDs. + Some gce-events are hardware-bound and cannot be changed by software. + For instance, in MT8195, when VDO0_MUTEX is stream done, VDO_MUTEX will + send an event signal to GCE, setting the value of event ID 597 to 1. + Similarly, in MT8188, the value of event ID 574 will be set to 1 when + VOD0_MUTEX is stream done. + On the other hand, some gce-events are not hardware-bound and can be + changed by software. For example, in MT8188, we can set the value of + event ID 855, which is not bound to any hardware, to 1 when the driver + in the secure world completes a task. However, in MT8195, event ID 855 + is already bound to VDEC_LAT1, so we need to select another event ID to + achieve the same purpose. This event ID can be any ID that is not bound + to any hardware and is not yet used in any software driver. + To determine if the event ID is bound to the hardware or used by a + software driver, refer to the GCE header + include/dt-bindings/gce/-gce.h of each chip. +$ref: /schemas/types.yaml#/definitions/uint32-array +minItems: 1 +maxItems: 1024 + +additionalProperties: true -- 2.18.0
Re: [PATCH v1 2/4] backlight: hx8357: Move OF table closer to its consumer
On Sun, Jan 21, 2024 at 03:49:23PM +0200, Andy Shevchenko wrote: > On Mon, Jan 15, 2024 at 09:22:19AM +0100, Javier Martinez Canillas wrote: > > Andy Shevchenko writes: > > ... > > > > + {} > > > > While at it, maybe add the { /* sentinel */ } convention to the last entry ? > > Maybe. Is it a common for this subsystem? I'd answer that slightly differently. Backlight does not aspire to be special regarding this sort of thing. If this pattern is becoming common within the rest of the kernel then its absolutely fine to use it here! There are certainly backlights that use this convention... although they are not yet the majority. Daniel.
Re: [PATCH] drm/rockchip: vop2: add a missing unlock in vop2_crtc_atomic_enable()
On Fri, Jan 19, 2024 at 11:08:40AM -0800, Harshit Mogalapalli wrote: > Unlock before returning on the error path. > > Fixes: 5a028e8f062f ("drm/rockchip: vop2: Add support for rk3588") > Signed-off-by: Harshit Mogalapalli Reviewed-by: Sascha Hauer Thanks for fixing this. Sascha > --- > This is based on static analysis. Only compile tested. > Note: Smatch found this. > --- > drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c > b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c > index 85b3b4871a1d..fdd768bbd487 100644 > --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c > @@ -1985,8 +1985,10 @@ static void vop2_crtc_atomic_enable(struct drm_crtc > *crtc, > clock = vop2_set_intf_mux(vp, rkencoder->crtc_endpoint_id, > polflags); > } > > - if (!clock) > + if (!clock) { > + vop2_unlock(vop2); > return; > + } > > if (vcstate->output_mode == ROCKCHIP_OUT_MODE_ && > !(vp_data->feature & VOP2_VP_FEATURE_OUTPUT_10BIT)) > -- > 2.39.3 > > -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- |
Re: [PATCH v3] drm: Check output polling initialized before disabling
Hi all, to me it seems like the patch has uncovered a genuine warning in drm_helper_probe_single_connector_modes() function. Before calling drm_kms_helper_poll_enable() there should be check to see if mode_config.poll_enabled is set similar to the new suspend/resume changes in the patch. Is this understanding correct? Thoughts? On Fri, Jan 19, 2024 at 02:46:47PM +0800, kernel test robot wrote: > > > Hello, > > kernel test robot noticed > "WARNING:at_drivers/gpu/drm/drm_probe_helper.c:#drm_kms_helper_poll_enable[drm_kms_helper]" > on: > > commit: 98a690eb11a5f722cfff1dd5c3ac46f9ba326919 ("[PATCH v3] drm: Check > output polling initialized before disabling") > url: > https://github.com/intel-lab-lkp/linux/commits/Shradha-Gupta/drm-Check-output-polling-initialized-before-disabling/20240115-124300 > base: git://anongit.freedesktop.org/drm/drm-misc drm-misc-next > patch subject: [PATCH v3] drm: Check output polling initialized before > disabling > > in testcase: boot > > compiler: gcc-12 > test machine: qemu-system-x86_64 -enable-kvm -cpu SandyBridge -smp 2 -m 16G > > (please refer to attached dmesg/kmsg for entire log/backtrace) > > > +---+++ > | > | 45017df303 | 98a690eb11 | > +---+++ > | > WARNING:at_drivers/gpu/drm/drm_probe_helper.c:#drm_kms_helper_poll_enable[drm_kms_helper] > | 0 | 8 | > | RIP:drm_kms_helper_poll_enable[drm_kms_helper] > | 0 | 8 | > +---+++ > > > If you fix the issue in a separate patch/commit (i.e. not just a new version > of > the same patch/commit), kindly add following tags > | Reported-by: kernel test robot > | Closes: > https://lore.kernel.org/oe-lkp/202401191128.db8423f1-oliver.s...@intel.com > > > > The kernel config and materials to reproduce are available at: > https://download.01.org/0day-ci/archive/20240119/202401191128.db8423f1-oliver.s...@intel.com > > > > [ 19.037694][ T142] [drm] Initialized bochs-drm 1.0.0 20130925 for > :00:02.0 on minor 0 > [ 19.038726][ T142] [ cut here ] > [ 19.039197][ T142] bochs-drm :00:02.0: > drm_WARN_ON_ONCE(!dev->mode_config.poll_enabled) > [ 19.039241][ T142] WARNING: CPU: 0 PID: 142 at > drivers/gpu/drm/drm_probe_helper.c:305 drm_kms_helper_poll_enable+0x329/0x410 > [drm_kms_helper] > [ 19.040963][ T142] Modules linked in: parport(+) bochs(+) joydev > serio_raw drm_vram_helper ata_piix(+) drm_ttm_helper ttm libata ipmi_devintf > ipmi_msghandler drm_kms_helper i2c_piix4 fuse drm ip_tables > [ 19.042413][ T142] CPU: 0 PID: 142 Comm: systemd-udevd Not tainted > 6.7.0-rc3-00770-g98a690eb11a5 #1 > [ 19.043146][ T142] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), > BIOS 1.16.2-debian-1.16.2-1 04/01/2014 > [ 19.043972][ T142] RIP: 0010:drm_kms_helper_poll_enable+0x329/0x410 > [drm_kms_helper] > [ 19.044685][ T142] Code: 48 8b 6b 50 48 85 ed 74 41 48 89 df e8 30 e0 5d > c3 48 c7 c1 e0 8c 4b c0 48 89 ea 48 c7 c7 40 8a 4b c0 48 89 c6 e8 77 a3 d3 c1 > <0f> 0b e9 ae fd ff ff e8 9b c6 53 c2 e9 4c fd ff ff 48 8b 7c 24 08 > [ 19.046268][ T142] RSP: :c97ef1c0 EFLAGS: 00010286 > [ 19.046755][ T142] RAX: RBX: 888121dc40c0 RCX: > 0027 > [ 19.047400][ T142] RDX: 0027 RSI: 0004 RDI: > 8883af030848 > [ 19.048042][ T142] RBP: 888121d84260 R08: 0001 R09: > ed1075e06109 > [ 19.048688][ T142] R10: 8883af03084b R11: 0001 R12: > 88815688a7a0 > [ 19.049362][ T142] R13: 192fde3b R14: R15: > 0003 > [ 19.050001][ T142] FS: () GS:8883af00(0063) > knlGS:f7950b00 > [ 19.050722][ T142] CS: 0010 DS: 002b ES: 002b CR0: 80050033 > [ 19.051259][ T142] CR2: 58b17d6c CR3: 00012463e000 CR4: > 000406f0 > [ 19.051892][ T142] DR0: DR1: DR2: > > [ 19.052568][ T142] DR3: DR6: fffe0ff0 DR7: > 0400 > [ 19.053242][ T142] Call Trace: > [ 19.053531][ T142] > [ 19.053780][ T142] ? __warn+0xcd/0x260 > [ 19.054149][ T142] ? drm_kms_helper_poll_enable+0x329/0x410 > [drm_kms_helper] > [ 19.054787][ T142] ? report_bug+0x267/0x2d0 > [ 19.055173][ T142] ? handle_bug+0x3c/0x70 > [ 19.055523][ T142] ? exc_invalid_op+0x17/0x40 > [ 19.055904][ T142] ? asm_exc_invalid_op+0x1a/0x20 > [ 19.056332][ T142] ? drm_kms_helper_poll_e
Re: [Linaro-mm-sig] [PATCH v5 1/6] dma-buf: Add dma_buf_{begin,end}_access()
Hi Christian, Le lundi 22 janvier 2024 à 11:35 +0100, Christian König a écrit : > Am 19.01.24 um 15:13 schrieb Paul Cercueil: > > These functions should be used by device drivers when they start > > and > > stop accessing the data of DMABUF. It allows DMABUF importers to > > cache > > the dma_buf_attachment while ensuring that the data they want to > > access > > is available for their device when the DMA transfers take place. > > As Daniel already noted as well this is a complete no-go from the > DMA-buf design point of view. What do you mean "as Daniel already noted"? It was him who suggested this. > > Regards, > Christian. Cheers, -Paul > > > > > Signed-off-by: Paul Cercueil > > > > --- > > v5: New patch > > --- > > drivers/dma-buf/dma-buf.c | 66 > > +++ > > include/linux/dma-buf.h | 37 ++ > > 2 files changed, 103 insertions(+) > > > > diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c > > index 8fe5aa67b167..a8bab6c18fcd 100644 > > --- a/drivers/dma-buf/dma-buf.c > > +++ b/drivers/dma-buf/dma-buf.c > > @@ -830,6 +830,8 @@ static struct sg_table * __map_dma_buf(struct > > dma_buf_attachment *attach, > > * - dma_buf_mmap() > > * - dma_buf_begin_cpu_access() > > * - dma_buf_end_cpu_access() > > + * - dma_buf_begin_access() > > + * - dma_buf_end_access() > > * - dma_buf_map_attachment_unlocked() > > * - dma_buf_unmap_attachment_unlocked() > > * - dma_buf_vmap_unlocked() > > @@ -1602,6 +1604,70 @@ void dma_buf_vunmap_unlocked(struct dma_buf > > *dmabuf, struct iosys_map *map) > > } > > EXPORT_SYMBOL_NS_GPL(dma_buf_vunmap_unlocked, DMA_BUF); > > > > +/** > > + * @dma_buf_begin_access - Call before any hardware access from/to > > the DMABUF > > + * @attach:[in]attachment used for hardware access > > + * @sg_table: [in]scatterlist used for the DMA transfer > > + * @direction: [in] direction of DMA transfer > > + */ > > +int dma_buf_begin_access(struct dma_buf_attachment *attach, > > +struct sg_table *sgt, enum > > dma_data_direction dir) > > +{ > > + struct dma_buf *dmabuf; > > + bool cookie; > > + int ret; > > + > > + if (WARN_ON(!attach)) > > + return -EINVAL; > > + > > + dmabuf = attach->dmabuf; > > + > > + if (!dmabuf->ops->begin_access) > > + return 0; > > + > > + cookie = dma_fence_begin_signalling(); > > + ret = dmabuf->ops->begin_access(attach, sgt, dir); > > + dma_fence_end_signalling(cookie); > > + > > + if (WARN_ON_ONCE(ret)) > > + return ret; > > + > > + return 0; > > +} > > +EXPORT_SYMBOL_NS_GPL(dma_buf_begin_access, DMA_BUF); > > + > > +/** > > + * @dma_buf_end_access - Call after any hardware access from/to > > the DMABUF > > + * @attach:[in]attachment used for hardware access > > + * @sg_table: [in]scatterlist used for the DMA transfer > > + * @direction: [in] direction of DMA transfer > > + */ > > +int dma_buf_end_access(struct dma_buf_attachment *attach, > > + struct sg_table *sgt, enum > > dma_data_direction dir) > > +{ > > + struct dma_buf *dmabuf; > > + bool cookie; > > + int ret; > > + > > + if (WARN_ON(!attach)) > > + return -EINVAL; > > + > > + dmabuf = attach->dmabuf; > > + > > + if (!dmabuf->ops->end_access) > > + return 0; > > + > > + cookie = dma_fence_begin_signalling(); > > + ret = dmabuf->ops->end_access(attach, sgt, dir); > > + dma_fence_end_signalling(cookie); > > + > > + if (WARN_ON_ONCE(ret)) > > + return ret; > > + > > + return 0; > > +} > > +EXPORT_SYMBOL_NS_GPL(dma_buf_end_access, DMA_BUF); > > + > > #ifdef CONFIG_DEBUG_FS > > static int dma_buf_debug_show(struct seq_file *s, void *unused) > > { > > diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h > > index 8ff4add71f88..8ba612c7cc16 100644 > > --- a/include/linux/dma-buf.h > > +++ b/include/linux/dma-buf.h > > @@ -246,6 +246,38 @@ struct dma_buf_ops { > > */ > > int (*end_cpu_access)(struct dma_buf *, enum > > dma_data_direction); > > > > + /** > > +* @begin_access: > > +* > > +* This is called from dma_buf_begin_access() when a > > device driver > > +* wants to access the data of the DMABUF. The exporter > > can use this > > +* to flush/sync the caches if needed. > > +* > > +* This callback is optional. > > +* > > +* Returns: > > +* > > +* 0 on success or a negative error code on failure. > > +*/ > > + int (*begin_access)(struct dma_buf_attachment *, struct > > sg_table *, > > + enum dma_data_direction); > > + > > + /** > > +* @end_access: > > +* > > +* This is called from dma_buf_end_access() when a device > > driver is > > +* done accessing the data of the DMABUF. The exporter can > > use this > > +* to flush/sync the caches if needed. > > +* > > +* T
[PATCH v2 01/47] vgacon: inline vc_scrolldelta_helper() into vgacon_scrolldelta()
Since commit 74d58cd48a8f ("USB: sisusbvga: remove console support"), vgacon_scrolldelta() is the only user of vc_scrolldelta_helper(). Inline the helper into vgacon_scrolldelta() and drop it. Signed-off-by: Jiri Slaby (SUSE) Cc: Helge Deller Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org --- drivers/tty/vt/vt.c| 40 -- drivers/video/console/vgacon.c | 36 -- include/linux/vt_kern.h| 3 --- 3 files changed, 34 insertions(+), 45 deletions(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 156efda7c80d..3f3f7c216819 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -4748,43 +4748,3 @@ void vcs_scr_updated(struct vc_data *vc) { notify_update(vc); } - -void vc_scrolldelta_helper(struct vc_data *c, int lines, - unsigned int rolled_over, void *base, unsigned int size) -{ - unsigned long ubase = (unsigned long)base; - ptrdiff_t scr_end = (void *)c->vc_scr_end - base; - ptrdiff_t vorigin = (void *)c->vc_visible_origin - base; - ptrdiff_t origin = (void *)c->vc_origin - base; - int margin = c->vc_size_row * 4; - int from, wrap, from_off, avail; - - /* Turn scrollback off */ - if (!lines) { - c->vc_visible_origin = c->vc_origin; - return; - } - - /* Do we have already enough to allow jumping from 0 to the end? */ - if (rolled_over > scr_end + margin) { - from = scr_end; - wrap = rolled_over + c->vc_size_row; - } else { - from = 0; - wrap = size; - } - - from_off = (vorigin - from + wrap) % wrap + lines * c->vc_size_row; - avail = (origin - from + wrap) % wrap; - - /* Only a little piece would be left? Show all incl. the piece! */ - if (avail < 2 * margin) - margin = 0; - if (from_off < margin) - from_off = 0; - if (from_off > avail - margin) - from_off = avail; - - c->vc_visible_origin = ubase + (from + from_off) % wrap; -} -EXPORT_SYMBOL_GPL(vc_scrolldelta_helper); diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 8ef1579fa57f..9176fff9ce6e 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -138,8 +138,40 @@ static inline void vga_set_mem_top(struct vc_data *c) static void vgacon_scrolldelta(struct vc_data *c, int lines) { - vc_scrolldelta_helper(c, lines, vga_rolled_over, (void *)vga_vram_base, - vga_vram_size); + unsigned long scr_end = c->vc_scr_end - vga_vram_base; + unsigned long vorigin = c->vc_visible_origin - vga_vram_base; + unsigned long origin = c->vc_origin - vga_vram_base; + int margin = c->vc_size_row * 4; + int from, wrap, from_off, avail; + + /* Turn scrollback off */ + if (!lines) { + c->vc_visible_origin = c->vc_origin; + return; + } + + /* Do we have already enough to allow jumping from 0 to the end? */ + if (vga_rolled_over > scr_end + margin) { + from = scr_end; + wrap = vga_rolled_over + c->vc_size_row; + } else { + from = 0; + wrap = vga_vram_size; + } + + from_off = (vorigin - from + wrap) % wrap + lines * c->vc_size_row; + avail = (origin - from + wrap) % wrap; + + /* Only a little piece would be left? Show all incl. the piece! */ + if (avail < 2 * margin) + margin = 0; + if (from_off < margin) + from_off = 0; + if (from_off > avail - margin) + from_off = avail; + + c->vc_visible_origin = vga_vram_base + (from + from_off) % wrap; + vga_set_mem_top(c); } diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h index c1f5aebef170..a789ea3ed2a0 100644 --- a/include/linux/vt_kern.h +++ b/include/linux/vt_kern.h @@ -168,7 +168,4 @@ void vt_set_led_state(unsigned int console, int leds); void vt_kbd_con_start(unsigned int console); void vt_kbd_con_stop(unsigned int console); -void vc_scrolldelta_helper(struct vc_data *c, int lines, - unsigned int rolled_over, void *_base, unsigned int size); - #endif /* _VT_KERN_H */ -- 2.43.0
[PATCH v2 07/47] tty: vt: pass vc_resize_user as a parameter
It is pretty unfortunate to set vc_data::vc_resize_user in two callers of vc_do_resize(). vc_resize_user is immediately reset there (while remembering it). So instead of this back and forth, pass 'from_user' as a parameter. Notes on 'int user': * The name changes from 'user' to 'from_user' on some places to be consistent. * The type is bool now as 'int user' might evoke user's uid or whatever. Provided vc_resize() is called on many places and they need not to care about this parameter, its prototype is kept unchanged. Instead, it is now an inline calling a new __vc_resize() which implements the above. This patch makes the situation much more obvious. Signed-off-by: Jiri Slaby (SUSE) Cc: Helge Deller Cc: Daniel Vetter Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org --- drivers/tty/vt/vt.c | 28 +--- drivers/tty/vt/vt_ioctl.c| 6 ++ drivers/video/console/vgacon.c | 4 ++-- drivers/video/fbdev/core/fbcon.c | 2 +- include/linux/console.h | 2 +- include/linux/console_struct.h | 1 - include/linux/vt_kern.h | 9 - 7 files changed, 27 insertions(+), 25 deletions(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 3a6f60ad2224..c87837306074 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -1115,13 +1115,13 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */ } static inline int resize_screen(struct vc_data *vc, int width, int height, - int user) + bool from_user) { /* Resizes the resolution of the display adapater */ int err = 0; if (vc->vc_sw->con_resize) - err = vc->vc_sw->con_resize(vc, width, height, user); + err = vc->vc_sw->con_resize(vc, width, height, from_user); return err; } @@ -1132,6 +1132,7 @@ static inline int resize_screen(struct vc_data *vc, int width, int height, * @vc: virtual console private data * @cols: columns * @lines: lines + * @from_user: invoked by a user? * * Resize a virtual console, clipping according to the actual constraints. * If the caller passes a tty structure then update the termios winsize @@ -1142,21 +1143,17 @@ static inline int resize_screen(struct vc_data *vc, int width, int height, */ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, - unsigned int cols, unsigned int lines) + unsigned int cols, unsigned int lines, bool from_user) { unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0; unsigned long end; unsigned int old_rows, old_row_size, first_copied_row; unsigned int new_cols, new_rows, new_row_size, new_screen_size; - unsigned int user; unsigned short *oldscreen, *newscreen; u32 **new_uniscr = NULL; WARN_CONSOLE_UNLOCKED(); - user = vc->vc_resize_user; - vc->vc_resize_user = 0; - if (cols > VC_MAXCOL || lines > VC_MAXROW) return -EINVAL; @@ -1182,7 +1179,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, * to deal with possible errors from the code below, we call * the resize_screen here as well. */ - return resize_screen(vc, new_cols, new_rows, user); + return resize_screen(vc, new_cols, new_rows, from_user); } if (new_screen_size > KMALLOC_MAX_SIZE || !new_screen_size) @@ -1205,7 +1202,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, old_rows = vc->vc_rows; old_row_size = vc->vc_size_row; - err = resize_screen(vc, new_cols, new_rows, user); + err = resize_screen(vc, new_cols, new_rows, from_user); if (err) { kfree(newscreen); vc_uniscr_free(new_uniscr); @@ -1292,22 +1289,23 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, } /** - * vc_resize - resize a VT + * __vc_resize - resize a VT * @vc: virtual console * @cols: columns * @rows: rows + * @from_user: invoked by a user? * * Resize a virtual console as seen from the console end of things. We * use the common vc_do_resize methods to update the structures. The * caller must hold the console sem to protect console internals and * vc->port.tty */ - -int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int rows) +int __vc_resize(struct vc_data *vc, unsigned int cols, unsigned int rows, + bool from_user) { - return vc_do_resize(vc->port.tty, vc, cols, rows); + return vc_do_resize(vc->port.tty, vc, cols, rows, from_user); } -EXPORT_SYMBOL(vc_resize); +EXPORT_SYMBOL(__vc_resize); /** * vt_resize - resize a VT @@
[PATCH v2 00/47] tty: vt: cleanup and documentation
Push the console code (vt.c, vt.h, console.h, ...) into a bit more maintainable state. Especially all around consw structure and document it. CSI parser is also a bit cleaned up. More to follow some time in the next round. [v2] See respective patches for changes. The major changes: * vesa.h introduced * parameters of csi*() simplified Cc: Daniel Vetter Cc: dri-devel@lists.freedesktop.org Cc: Helge Deller Cc: "James E.J. Bottomley" Cc: Jonathan Corbet Cc: linux-...@vger.kernel.org Cc: linux-fb...@vger.kernel.org Cc: linux-par...@vger.kernel.org Cc: Martin Hostettler Cc: Thomas Zimmermann Jiri Slaby (SUSE) (47): vgacon: inline vc_scrolldelta_helper() into vgacon_scrolldelta() fbcon: make display_desc a static array in fbcon_startup() tty: vt: fix 20 vs 0x20 typo in EScsiignore tty: vt: expect valid vc when in tty ops tty: vt: pass proper pointers from tioclinux() tty: vt: push console lock from tioclinux() down to 2 functions tty: vt: pass vc_resize_user as a parameter tty: vt: make vc_is_sel()'s vc const tty: vt: define an enum for CSI+m codes tty: vt: use case ranges for CSI+m fg/bg colors tty: vt: define an enum for CSI+J codes tty: vt: reflow csi_J() use clamp() for counts in csi_?() handlers don't pass vc->vc_par[0] to csi_?() handlers tty: vt: define an enum for CSI+K codes tty: vt: reflow csi_K() tty: vt: define an enum for ascii characters tty: vt: remove extern from functions in selection.h tty: vt: make consw::con_debug_*() return void tty: vt: make init parameter of consw::con_init() a bool tty: vt: sanitize arguments of consw::con_clear() tty: vt: remove checks for count in consw::con_clear() implementations tty: vt: add con_putc() helper tty: vt: eliminate unneeded consw::con_putc() implementations tty: vt: sanitize consw::con_putc() parameters tty: vt: sanitize consw::con_putcs() parameters consoles: use if instead of switch-case in consw::con_cursor() fbdev/core: simplify cursor_state setting in fbcon_ops::cursor() tty: vt: remove CM_* constants tty: vt: make consw::con_switch() return a bool tty: vt: stop using -1 for blank mode in consw::con_blank() tty: vt: define a common enum for VESA blanking constants tty: vt: use VESA blanking constants tty: vt: use enum constants for VESA blanking modes tty: vt: make types around consw::con_blank() bool tty: vt: make font of consw::con_font_set() const tty: vt: make consw::con_font_default()'s name const tty: vt: change consw::con_set_origin() return type fbcon: remove consw::con_screen_pos() tty: vt: remove consw::con_screen_pos() tty: vt: make types of screenpos() more consistent fbcon: remove fbcon_getxy() tty: vt: remove consw::con_getxy() tty: vt: remove unused consw::con_flush_scrollback() tty: vt: document the rest of struct consw tty: vt: fix up kernel-doc Documentation: add console.rst Documentation/driver-api/tty/console.rst | 45 ++ Documentation/driver-api/tty/index.rst | 1 + drivers/tty/vt/selection.c | 43 +- drivers/tty/vt/vt.c | 645 +++ drivers/tty/vt/vt_ioctl.c| 6 +- drivers/video/console/dummycon.c | 38 +- drivers/video/console/mdacon.c | 43 +- drivers/video/console/newport_con.c | 69 +-- drivers/video/console/sticon.c | 79 ++- drivers/video/console/vgacon.c | 152 +++--- drivers/video/fbdev/core/bitblit.c | 13 +- drivers/video/fbdev/core/fbcon.c | 123 ++--- drivers/video/fbdev/core/fbcon.h | 4 +- drivers/video/fbdev/core/fbcon_ccw.c | 13 +- drivers/video/fbdev/core/fbcon_cw.c | 13 +- drivers/video/fbdev/core/fbcon_ud.c | 13 +- drivers/video/fbdev/core/tileblit.c | 4 +- include/linux/console.h | 124 +++-- include/linux/console_struct.h | 1 - include/linux/selection.h| 56 +- include/linux/vt_kern.h | 12 +- include/uapi/linux/fb.h | 8 +- include/uapi/linux/vesa.h| 18 + 23 files changed, 755 insertions(+), 768 deletions(-) create mode 100644 Documentation/driver-api/tty/console.rst create mode 100644 include/uapi/linux/vesa.h -- 2.43.0
[PATCH v2 02/47] fbcon: make display_desc a static array in fbcon_startup()
display_desc is a pointer to a RO string. Instead, switch display_desc to a static array as we are used to. It BTW saves unnecessary 8B on the stack. Signed-off-by: Jiri Slaby (SUSE) Cc: Daniel Vetter Cc: Helge Deller Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org --- drivers/video/fbdev/core/fbcon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 63af6ab034b5..a8c32cb4c878 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -921,7 +921,7 @@ static void display_to_var(struct fb_var_screeninfo *var, static const char *fbcon_startup(void) { - const char *display_desc = "frame buffer device"; + static const char display_desc[] = "frame buffer device"; struct fbcon_display *p = &fb_display[fg_console]; struct vc_data *vc = vc_cons[fg_console].d; const struct font_desc *font = NULL; -- 2.43.0
[PATCH v2 20/47] tty: vt: make init parameter of consw::con_init() a bool
The 'init' parameter of consw::con_init() is true for the first call of the hook on a particular console. So make the parameter a bool. And document the hook. Signed-off-by: Jiri Slaby (SUSE) Reviewed-by: Geert Uytterhoeven Cc: Helge Deller Cc: "James E.J. Bottomley" Cc: Daniel Vetter Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linux-par...@vger.kernel.org --- Notes: [v2] fix up the comment (Geert) drivers/tty/vt/vt.c | 8 drivers/video/console/dummycon.c| 2 +- drivers/video/console/mdacon.c | 2 +- drivers/video/console/newport_con.c | 2 +- drivers/video/console/sticon.c | 2 +- drivers/video/console/vgacon.c | 4 ++-- drivers/video/fbdev/core/fbcon.c| 2 +- include/linux/console.h | 4 +++- 8 files changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index bbfda0d33ca1..fcb41c8724f3 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -999,7 +999,7 @@ int vc_cons_allocated(unsigned int i) return (i < MAX_NR_CONSOLES && vc_cons[i].d); } -static void visual_init(struct vc_data *vc, int num, int init) +static void visual_init(struct vc_data *vc, int num, bool init) { /* ++Geert: vc->vc_sw->con_init determines console size */ if (vc->vc_sw) @@ -1083,7 +1083,7 @@ int vc_allocate(unsigned int currcons)/* return 0 on success */ vc->port.ops = &vc_port_ops; INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); - visual_init(vc, currcons, 1); + visual_init(vc, currcons, true); if (!*vc->uni_pagedict_loc) con_set_default_unimap(vc); @@ -3513,7 +3513,7 @@ static int __init con_init(void) vc_cons[currcons].d = vc = kzalloc(sizeof(struct vc_data), GFP_NOWAIT); INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); tty_port_init(&vc->port); - visual_init(vc, currcons, 1); + visual_init(vc, currcons, true); /* Assuming vc->vc_{cols,rows,screenbuf_size} are sane here. */ vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT); vc_init(vc, currcons || !vc->vc_sw->con_save_screen); @@ -3682,7 +3682,7 @@ static int do_bind_con_driver(const struct consw *csw, int first, int last, old_was_color = vc->vc_can_do_color; vc->vc_sw->con_deinit(vc); vc->vc_origin = (unsigned long)vc->vc_screenbuf; - visual_init(vc, i, 0); + visual_init(vc, i, false); set_origin(vc); update_attr(vc); diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c index 14af5d9e13b0..f2cef9d9a4b5 100644 --- a/drivers/video/console/dummycon.c +++ b/drivers/video/console/dummycon.c @@ -98,7 +98,7 @@ static const char *dummycon_startup(void) return "dummy device"; } -static void dummycon_init(struct vc_data *vc, int init) +static void dummycon_init(struct vc_data *vc, bool init) { vc->vc_can_do_color = 1; if (init) { diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c index ef29b321967f..c5b255c96879 100644 --- a/drivers/video/console/mdacon.c +++ b/drivers/video/console/mdacon.c @@ -352,7 +352,7 @@ static const char *mdacon_startup(void) return "MDA-2"; } -static void mdacon_init(struct vc_data *c, int init) +static void mdacon_init(struct vc_data *c, bool init) { c->vc_complement_mask = 0x0800; /* reverse video */ c->vc_display_fg = &mda_display_fg; diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index e8e4f82cd4a1..12c64ef47087 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -324,7 +324,7 @@ static const char *newport_startup(void) return NULL; } -static void newport_init(struct vc_data *vc, int init) +static void newport_init(struct vc_data *vc, bool init) { int cols, rows; diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index 992a4fa431aa..0bfeabc3f7c7 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -273,7 +273,7 @@ static int sticon_font_set(struct vc_data *vc, struct console_font *font, return sticon_set_font(vc, font, vpitch); } -static void sticon_init(struct vc_data *c, int init) +static void sticon_init(struct vc_data *c, bool init) { struct sti_struct *sti = sticon_sti; int vc_cols, vc_rows; diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 0c76e2817b49..5d523753def8 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -367,7 +367,7 @@ static const char *vgacon_startup(void) return display_desc; } -static void vgacon_init(struct vc_data *c, int init) +static void vgacon_init(struct vc_data *c, bool init) { str
[PATCH v2 22/47] tty: vt: remove checks for count in consw::con_clear() implementations
'count' in consw::con_clear() is guaranteed to be positive. csi_X() (the only caller) takes the minimum of the vc parameter (which is at least 1) and count of characters till the end of the line. The latter is computed as a subtraction of vc->vc_cols (count) and vc->state.x (offset). So for the worst case, full line, it is 1. Therefore, there is no point in checking zero or negative values (width is now unsigned anyway). Signed-off-by: Jiri Slaby (SUSE) Cc: Helge Deller Cc: "James E.J. Bottomley" Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linux-par...@vger.kernel.org --- drivers/video/console/mdacon.c | 3 --- drivers/video/console/sticon.c | 3 --- 2 files changed, 6 deletions(-) diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c index 1ddbb6cd5b0c..2ff2c9394d40 100644 --- a/drivers/video/console/mdacon.c +++ b/drivers/video/console/mdacon.c @@ -448,9 +448,6 @@ static void mdacon_clear(struct vc_data *c, unsigned int y, unsigned int x, u16 *dest = mda_addr(x, y); u16 eattr = mda_convert_attr(c->vc_video_erase_char); - if (width <= 0) - return; - scr_memsetw(dest, eattr, width * 2); } diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index d99c2a659bfd..b1d972d9a31c 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -303,9 +303,6 @@ static void sticon_deinit(struct vc_data *c) static void sticon_clear(struct vc_data *conp, unsigned int sy, unsigned int sx, unsigned int width) { -if (!width) - return; - sti_clear(sticon_sti, sy, sx, 1, width, conp->vc_video_erase_char, font_data[conp->vc_num]); } -- 2.43.0
[PATCH v2 28/47] fbdev/core: simplify cursor_state setting in fbcon_ops::cursor()
There is a switch decicing if cursor should be drawn or not. The whole switch can be simplified to one line. Do this cleanup as a preparatory work for the next patch. There, all the CM_* constants are removed. Signed-off-by: Jiri Slaby (SUSE) Cc: Daniel Vetter Cc: Helge Deller Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org --- drivers/video/fbdev/core/bitblit.c | 11 +-- drivers/video/fbdev/core/fbcon_ccw.c | 11 +-- drivers/video/fbdev/core/fbcon_cw.c | 11 +-- drivers/video/fbdev/core/fbcon_ud.c | 11 +-- 4 files changed, 4 insertions(+), 40 deletions(-) diff --git a/drivers/video/fbdev/core/bitblit.c b/drivers/video/fbdev/core/bitblit.c index 8587c9da0670..daff152f4c22 100644 --- a/drivers/video/fbdev/core/bitblit.c +++ b/drivers/video/fbdev/core/bitblit.c @@ -348,16 +348,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode, mask[i++] = msk; } - switch (mode) { - case CM_ERASE: - ops->cursor_state.enable = 0; - break; - case CM_DRAW: - case CM_MOVE: - default: - ops->cursor_state.enable = (use_sw) ? 0 : 1; - break; - } + ops->cursor_state.enable = (mode != CM_ERASE) && !use_sw; cursor.image.data = src; cursor.image.fg_color = ops->cursor_state.image.fg_color; diff --git a/drivers/video/fbdev/core/fbcon_ccw.c b/drivers/video/fbdev/core/fbcon_ccw.c index 2789ace79634..889423d580bc 100644 --- a/drivers/video/fbdev/core/fbcon_ccw.c +++ b/drivers/video/fbdev/core/fbcon_ccw.c @@ -349,16 +349,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode, kfree(tmp); } - switch (mode) { - case CM_ERASE: - ops->cursor_state.enable = 0; - break; - case CM_DRAW: - case CM_MOVE: - default: - ops->cursor_state.enable = (use_sw) ? 0 : 1; - break; - } + ops->cursor_state.enable = (mode != CM_ERASE) && !use_sw; cursor.image.data = src; cursor.image.fg_color = ops->cursor_state.image.fg_color; diff --git a/drivers/video/fbdev/core/fbcon_cw.c b/drivers/video/fbdev/core/fbcon_cw.c index 86a254c1b2b7..a306ca5802e8 100644 --- a/drivers/video/fbdev/core/fbcon_cw.c +++ b/drivers/video/fbdev/core/fbcon_cw.c @@ -332,16 +332,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode, kfree(tmp); } - switch (mode) { - case CM_ERASE: - ops->cursor_state.enable = 0; - break; - case CM_DRAW: - case CM_MOVE: - default: - ops->cursor_state.enable = (use_sw) ? 0 : 1; - break; - } + ops->cursor_state.enable = (mode != CM_ERASE) && !use_sw; cursor.image.data = src; cursor.image.fg_color = ops->cursor_state.image.fg_color; diff --git a/drivers/video/fbdev/core/fbcon_ud.c b/drivers/video/fbdev/core/fbcon_ud.c index 23bc045769d0..f6fc458b46c7 100644 --- a/drivers/video/fbdev/core/fbcon_ud.c +++ b/drivers/video/fbdev/core/fbcon_ud.c @@ -372,16 +372,7 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode, mask[i++] = ~msk; } - switch (mode) { - case CM_ERASE: - ops->cursor_state.enable = 0; - break; - case CM_DRAW: - case CM_MOVE: - default: - ops->cursor_state.enable = (use_sw) ? 0 : 1; - break; - } + ops->cursor_state.enable = (mode != CM_ERASE) && !use_sw; cursor.image.data = src; cursor.image.fg_color = ops->cursor_state.image.fg_color; -- 2.43.0
[PATCH v2 29/47] tty: vt: remove CM_* constants
There is no difference between CM_MOVE and CM_DRAW. Either of them enables the cursor. CM_ERASE then disables cursor. So get rid of all of them and use simple "bool enable". Note that this propagates down to the fbcon code. And document the hook. Signed-off-by: Jiri Slaby (SUSE) Cc: Helge Deller Cc: "James E.J. Bottomley" Cc: Daniel Vetter Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linux-par...@vger.kernel.org --- drivers/tty/vt/vt.c | 4 ++-- drivers/video/console/dummycon.c | 2 +- drivers/video/console/mdacon.c | 4 ++-- drivers/video/console/newport_con.c | 4 ++-- drivers/video/console/sticon.c | 6 +++--- drivers/video/console/vgacon.c | 6 +++--- drivers/video/fbdev/core/bitblit.c | 4 ++-- drivers/video/fbdev/core/fbcon.c | 19 +-- drivers/video/fbdev/core/fbcon.h | 4 ++-- drivers/video/fbdev/core/fbcon_ccw.c | 4 ++-- drivers/video/fbdev/core/fbcon_cw.c | 4 ++-- drivers/video/fbdev/core/fbcon_ud.c | 4 ++-- drivers/video/fbdev/core/tileblit.c | 4 ++-- include/linux/console.h | 8 ++-- 14 files changed, 36 insertions(+), 41 deletions(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 6091ffcf93d8..e4edcaf9d0a3 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -860,7 +860,7 @@ static void hide_cursor(struct vc_data *vc) if (vc_is_sel(vc)) clear_selection(); - vc->vc_sw->con_cursor(vc, CM_ERASE); + vc->vc_sw->con_cursor(vc, false); hide_softcursor(vc); } @@ -873,7 +873,7 @@ static void set_cursor(struct vc_data *vc) clear_selection(); add_softcursor(vc); if (CUR_SIZE(vc->vc_cursor_type) != CUR_NONE) - vc->vc_sw->con_cursor(vc, CM_DRAW); + vc->vc_sw->con_cursor(vc, true); } else hide_cursor(vc); } diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c index 188d9f3e201c..1171e27edef7 100644 --- a/drivers/video/console/dummycon.c +++ b/drivers/video/console/dummycon.c @@ -113,7 +113,7 @@ static void dummycon_init(struct vc_data *vc, bool init) static void dummycon_deinit(struct vc_data *vc) { } static void dummycon_clear(struct vc_data *vc, unsigned int sy, unsigned int sx, unsigned int width) { } -static void dummycon_cursor(struct vc_data *vc, int mode) { } +static void dummycon_cursor(struct vc_data *vc, bool enable) { } static bool dummycon_scroll(struct vc_data *vc, unsigned int top, unsigned int bottom, enum con_scroll dir, diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c index b8822b615b2f..bc851a1d9f4d 100644 --- a/drivers/video/console/mdacon.c +++ b/drivers/video/console/mdacon.c @@ -470,9 +470,9 @@ static int mdacon_blank(struct vc_data *c, int blank, int mode_switch) } } -static void mdacon_cursor(struct vc_data *c, int mode) +static void mdacon_cursor(struct vc_data *c, bool enable) { - if (mode == CM_ERASE) { + if (!enable) { mda_set_cursor(mda_vram_len - 1); return; } diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index f852717b88f0..e35406dea7c7 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -438,14 +438,14 @@ static void newport_putcs(struct vc_data *vc, const u16 *s, } } -static void newport_cursor(struct vc_data *vc, int mode) +static void newport_cursor(struct vc_data *vc, bool enable) { unsigned short treg; int xcurs, ycurs; treg = newport_vc2_get(npregs, VC2_IREG_CONTROL); - if (mode == CM_ERASE) { + if (!enable) { newport_vc2_set(npregs, VC2_IREG_CONTROL, (treg & ~(VC2_CTRL_ECDISP))); return; diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index 42480874db00..786e1b3a98ea 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -86,7 +86,7 @@ static void sticon_putcs(struct vc_data *conp, const u16 *s, unsigned int count, } } -static void sticon_cursor(struct vc_data *conp, int mode) +static void sticon_cursor(struct vc_data *conp, bool enable) { unsigned short car1; @@ -95,7 +95,7 @@ static void sticon_cursor(struct vc_data *conp, int mode) return; car1 = conp->vc_screenbuf[conp->state.x + conp->state.y * conp->vc_cols]; -if (mode == CM_ERASE) { +if (!enable) { sti_putc(sticon_sti, car1, conp->state.y, conp->state.x, font_data[conp->vc_num]); return; @@ -121,7 +121,7 @@ static bool sticon_scroll(struct vc_data *conp, unsigned int t, if (vga_is_gfx) return false; -sticon_cursor(conp, CM_ERASE); +sticon_cursor(conp, fa
[PATCH v2 19/47] tty: vt: make consw::con_debug_*() return void
The return value of con_debug_enter() and con_debug_leave() is ignored on many fronts. So just don't propagate errors (the current implementations return 0 anyway) and make the return type a void. Signed-off-by: Jiri Slaby (SUSE) Cc: Daniel Vetter Cc: Helge Deller Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org --- drivers/tty/vt/vt.c | 21 - drivers/video/fbdev/core/fbcon.c | 6 ++ include/linux/console.h | 18 ++ 3 files changed, 12 insertions(+), 33 deletions(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 51a2787415db..bbfda0d33ca1 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -4012,15 +4012,9 @@ EXPORT_SYMBOL(con_is_visible); * Called when the console is taken over by the kernel debugger, this * function needs to save the current console state, then put the console * into a state suitable for the kernel debugger. - * - * RETURNS: - * Zero on success, nonzero if a failure occurred when trying to prepare - * the console for the debugger. */ -int con_debug_enter(struct vc_data *vc) +void con_debug_enter(struct vc_data *vc) { - int ret = 0; - saved_fg_console = fg_console; saved_last_console = last_console; saved_want_console = want_console; @@ -4029,7 +4023,7 @@ int con_debug_enter(struct vc_data *vc) vc->vc_mode = KD_TEXT; console_blanked = 0; if (vc->vc_sw->con_debug_enter) - ret = vc->vc_sw->con_debug_enter(vc); + vc->vc_sw->con_debug_enter(vc); #ifdef CONFIG_KGDB_KDB /* Set the initial LINES variable if it is not already set */ if (vc->vc_rows < 999) { @@ -4059,7 +4053,6 @@ int con_debug_enter(struct vc_data *vc) } } #endif /* CONFIG_KGDB_KDB */ - return ret; } EXPORT_SYMBOL_GPL(con_debug_enter); @@ -4068,15 +4061,10 @@ EXPORT_SYMBOL_GPL(con_debug_enter); * * Restore the console state to what it was before the kernel debugger * was invoked. - * - * RETURNS: - * Zero on success, nonzero if a failure occurred when trying to restore - * the console. */ -int con_debug_leave(void) +void con_debug_leave(void) { struct vc_data *vc; - int ret = 0; fg_console = saved_fg_console; last_console = saved_last_console; @@ -4086,8 +4074,7 @@ int con_debug_leave(void) vc = vc_cons[fg_console].d; if (vc->vc_sw->con_debug_leave) - ret = vc->vc_sw->con_debug_leave(vc); - return ret; + vc->vc_sw->con_debug_leave(vc); } EXPORT_SYMBOL_GPL(con_debug_leave); diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index dd2f4617485c..d3fb98084eda 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -2243,7 +2243,7 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) return 0; } -static int fbcon_debug_enter(struct vc_data *vc) +static void fbcon_debug_enter(struct vc_data *vc) { struct fb_info *info = fbcon_info_from_console(vc->vc_num); struct fbcon_ops *ops = info->fbcon_par; @@ -2253,10 +2253,9 @@ static int fbcon_debug_enter(struct vc_data *vc) if (info->fbops->fb_debug_enter) info->fbops->fb_debug_enter(info); fbcon_set_palette(vc, color_table); - return 0; } -static int fbcon_debug_leave(struct vc_data *vc) +static void fbcon_debug_leave(struct vc_data *vc) { struct fb_info *info = fbcon_info_from_console(vc->vc_num); struct fbcon_ops *ops = info->fbcon_par; @@ -2264,7 +2263,6 @@ static int fbcon_debug_leave(struct vc_data *vc) ops->graphics = ops->save_graphics; if (info->fbops->fb_debug_leave) info->fbops->fb_debug_leave(info); - return 0; } static int fbcon_get_font(struct vc_data *vc, struct console_font *font, unsigned int vpitch) diff --git a/include/linux/console.h b/include/linux/console.h index 38b379d6c624..93a1db5bf3b5 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -88,11 +88,11 @@ struct consw { * limited to, unblanking the console, loading an appropriate * palette, and allowing debugger generated output. */ - int (*con_debug_enter)(struct vc_data *vc); + void(*con_debug_enter)(struct vc_data *vc); /* * Restore the console to its pre-debug state as closely as possible. */ - int (*con_debug_leave)(struct vc_data *vc); + void(*con_debug_leave)(struct vc_data *vc); }; extern const struct consw *conswitchp; @@ -113,17 +113,11 @@ int do_unregister_con_driver(const struct consw *csw); int do_take_over_console(const struct consw *sw, int first, int last, int deflt); void give_up_console(const struct consw *sw); #ifdef CONFIG_HW_CONSOLE -int con_debug_enter(struct vc_data *vc); -int con_debug_leave(void); +void con_debug_enter(struct
[PATCH v2 31/47] tty: vt: stop using -1 for blank mode in consw::con_blank()
-1 is the same as VESA_VSYNC_SUSPEND in all con_blank() implementations. So we can remove this special case from vgacon now too. Despite con_blank() of fbcon looks complicated, the "if (!fbcon_is_inactive(vc, info))" branch is not taken as we set "ops->graphics = 1;" few lines above. So what matters there (as in all other blank implementations except vgacon) is if 'blank' is zero or not. Signed-off-by: Jiri Slaby (SUSE) Cc: Helge Deller Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org --- drivers/tty/vt/vt.c| 2 +- drivers/video/console/vgacon.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index fd868046f586..13be125a06aa 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -4347,7 +4347,7 @@ void do_blank_screen(int entering_gfx) if (entering_gfx) { hide_cursor(vc); save_screen(vc); - vc->vc_sw->con_blank(vc, -1, 1); + vc->vc_sw->con_blank(vc, 1, 1); console_blanked = fg_console + 1; blank_state = blank_off; set_origin(vc); diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index f89eb53c0b79..804b6a180b60 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -814,7 +814,6 @@ static int vgacon_blank(struct vc_data *c, int blank, int mode_switch) /* Tell console.c that it has to restore the screen itself */ return 1; case 1: /* Normal blanking */ - case -1:/* Obsolete */ if (!mode_switch && vga_video_type == VIDEO_TYPE_VGAC) { vga_pal_blank(&vgastate); vga_palette_blanked = true; -- 2.43.0
[PATCH v2 21/47] tty: vt: sanitize arguments of consw::con_clear()
In consw::con_clear(): * Height is always 1, so drop it. * Offsets and width are always unsigned values, so re-type them as such. This needs a new __fbcon_clear() in the fbcon code to still handle height which might not be 1 when called internally. Note that tests for negative count/width are left in place -- they are taken care of in the next patches. And document the hook. Signed-off-by: Jiri Slaby (SUSE) Cc: Helge Deller Cc: "James E.J. Bottomley" Cc: Daniel Vetter Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linux-par...@vger.kernel.org --- drivers/tty/vt/vt.c | 2 +- drivers/video/console/dummycon.c| 4 ++-- drivers/video/console/mdacon.c | 15 +- drivers/video/console/newport_con.c | 6 +++--- drivers/video/console/sticon.c | 8 drivers/video/console/vgacon.c | 4 ++-- drivers/video/fbdev/core/fbcon.c| 32 + include/linux/console.h | 5 +++-- 8 files changed, 39 insertions(+), 37 deletions(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index fcb41c8724f3..b6f1449421bc 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -1585,7 +1585,7 @@ static void csi_X(struct vc_data *vc) vc_uniscr_clear_line(vc, vc->state.x, count); scr_memsetw((unsigned short *)vc->vc_pos, vc->vc_video_erase_char, 2 * count); if (con_should_update(vc)) - vc->vc_sw->con_clear(vc, vc->state.y, vc->state.x, 1, count); + vc->vc_sw->con_clear(vc, vc->state.y, vc->state.x, count); vc->vc_need_wrap = 0; } diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c index f2cef9d9a4b5..0a69d5c216ee 100644 --- a/drivers/video/console/dummycon.c +++ b/drivers/video/console/dummycon.c @@ -109,8 +109,8 @@ static void dummycon_init(struct vc_data *vc, bool init) } static void dummycon_deinit(struct vc_data *vc) { } -static void dummycon_clear(struct vc_data *vc, int sy, int sx, int height, - int width) { } +static void dummycon_clear(struct vc_data *vc, unsigned int sy, unsigned int sx, + unsigned int width) { } static void dummycon_cursor(struct vc_data *vc, int mode) { } static bool dummycon_scroll(struct vc_data *vc, unsigned int top, diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c index c5b255c96879..1ddbb6cd5b0c 100644 --- a/drivers/video/console/mdacon.c +++ b/drivers/video/console/mdacon.c @@ -442,23 +442,18 @@ static void mdacon_putcs(struct vc_data *c, const unsigned short *s, } } -static void mdacon_clear(struct vc_data *c, int y, int x, - int height, int width) +static void mdacon_clear(struct vc_data *c, unsigned int y, unsigned int x, +unsigned int width) { u16 *dest = mda_addr(x, y); u16 eattr = mda_convert_attr(c->vc_video_erase_char); - if (width <= 0 || height <= 0) + if (width <= 0) return; - if (x==0 && width==mda_num_columns) { - scr_memsetw(dest, eattr, height*width*2); - } else { - for (; height > 0; height--, dest+=mda_num_columns) - scr_memsetw(dest, eattr, width*2); - } + scr_memsetw(dest, eattr, width * 2); } - + static int mdacon_switch(struct vc_data *c) { return 1; /* redrawing needed */ diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index 12c64ef47087..55c6106b3507 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -346,12 +346,12 @@ static void newport_deinit(struct vc_data *c) } } -static void newport_clear(struct vc_data *vc, int sy, int sx, int height, - int width) +static void newport_clear(struct vc_data *vc, unsigned int sy, unsigned int sx, + unsigned int width) { int xend = ((sx + width) << 3) - 1; int ystart = ((sy << 4) + topscan) & 0x3ff; - int yend = (((sy + height) << 4) + topscan - 1) & 0x3ff; + int yend = (((sy + 1) << 4) + topscan - 1) & 0x3ff; if (logo_active) return; diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index 0bfeabc3f7c7..d99c2a659bfd 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -300,13 +300,13 @@ static void sticon_deinit(struct vc_data *c) sticon_set_def_font(i); } -static void sticon_clear(struct vc_data *conp, int sy, int sx, int height, -int width) +static void sticon_clear(struct vc_data *conp, unsigned int sy, unsigned int sx, +unsigned int width) { -if (!height || !width) +if (!width) return; -sti_clear(sticon_sti, sy, sx, height, width, +sti_clear(sticon_sti, sy, sx, 1, width,
[PATCH v2 33/47] tty: vt: use VESA blanking constants
There are VESA blanking constants defined in vesa.h. So use them in the console code instead of constant values. Signed-off-by: Jiri Slaby (SUSE) Cc: Helge Deller Cc: "James E.J. Bottomley" Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linux-par...@vger.kernel.org --- Notes: [v2] reword the commit log after vesa.h introduction drivers/tty/vt/vt.c | 9 + drivers/video/console/newport_con.c | 2 +- drivers/video/console/sticon.c | 2 +- drivers/video/console/vgacon.c | 6 +++--- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 13be125a06aa..0d5d7b5074a4 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -4320,7 +4320,7 @@ static int set_vesa_blanking(u8 __user *mode_user) return -EFAULT; console_lock(); - vesa_blank_mode = (mode < 4) ? mode : 0; + vesa_blank_mode = (mode < 4) ? mode : VESA_NO_BLANKING; console_unlock(); return 0; @@ -4347,7 +4347,7 @@ void do_blank_screen(int entering_gfx) if (entering_gfx) { hide_cursor(vc); save_screen(vc); - vc->vc_sw->con_blank(vc, 1, 1); + vc->vc_sw->con_blank(vc, VESA_VSYNC_SUSPEND, 1); console_blanked = fg_console + 1; blank_state = blank_off; set_origin(vc); @@ -4368,7 +4368,8 @@ void do_blank_screen(int entering_gfx) save_screen(vc); /* In case we need to reset origin, blanking hook returns 1 */ - i = vc->vc_sw->con_blank(vc, vesa_off_interval ? 1 : (vesa_blank_mode + 1), 0); + i = vc->vc_sw->con_blank(vc, vesa_off_interval ? VESA_VSYNC_SUSPEND : +(vesa_blank_mode + 1), 0); console_blanked = fg_console + 1; if (i) set_origin(vc); @@ -4419,7 +4420,7 @@ void do_unblank_screen(int leaving_gfx) } console_blanked = 0; - if (vc->vc_sw->con_blank(vc, 0, leaving_gfx)) + if (vc->vc_sw->con_blank(vc, VESA_NO_BLANKING, leaving_gfx)) /* Low-level driver cannot restore -> do it ourselves */ update_screen(vc); if (console_blank_hook) diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index 039d1c9937d2..ad3a09142770 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -480,7 +480,7 @@ static int newport_blank(struct vc_data *c, int blank, int mode_switch) { unsigned short treg; - if (blank == 0) { + if (blank == VESA_NO_BLANKING) { /* unblank console */ treg = newport_vc2_get(npregs, VC2_IREG_CONTROL); newport_vc2_set(npregs, VC2_IREG_CONTROL, diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index f3bb48a0e980..817b89c45e81 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -300,7 +300,7 @@ static bool sticon_switch(struct vc_data *conp) static int sticon_blank(struct vc_data *c, int blank, int mode_switch) { -if (blank == 0) { +if (blank == VESA_NO_BLANKING) { if (mode_switch) vga_is_gfx = 0; return 1; diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 804b6a180b60..02eccd9b3542 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -800,10 +800,10 @@ static void vga_pal_blank(struct vgastate *state) static int vgacon_blank(struct vc_data *c, int blank, int mode_switch) { switch (blank) { - case 0: /* Unblank */ + case VESA_NO_BLANKING: /* Unblank */ if (vga_vesa_blanked) { vga_vesa_unblank(&vgastate); - vga_vesa_blanked = 0; + vga_vesa_blanked = VESA_NO_BLANKING; } if (vga_palette_blanked) { vga_set_palette(c, color_table); @@ -813,7 +813,7 @@ static int vgacon_blank(struct vc_data *c, int blank, int mode_switch) vga_is_gfx = false; /* Tell console.c that it has to restore the screen itself */ return 1; - case 1: /* Normal blanking */ + case VESA_VSYNC_SUSPEND:/* Normal blanking */ if (!mode_switch && vga_video_type == VIDEO_TYPE_VGAC) { vga_pal_blank(&vgastate); vga_palette_blanked = true; -- 2.43.0
[PATCH v2 32/47] tty: vt: define a common enum for VESA blanking constants
There are currently two places with VESA blanking constants definitions: fb.h and console.h. Extract/unify the two to a separate header (vesa.h). Given the fb's is in an uapi header, create the common header in uapi too. Note that instead of macros, an enum (vesa_blank_mode) is created. But the macros are kept too (they now expand to the enum constants), just in case someone in userspace performs some #ifdeffery. Signed-off-by: Jiri Slaby (SUSE) Cc: Helge Deller Cc: linux-ker...@vger.kernel.org Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: Thomas Zimmermann --- Notes: [v2] new in v2 include/linux/console.h | 7 +-- include/uapi/linux/fb.h | 8 +--- include/uapi/linux/vesa.h | 18 ++ 3 files changed, 20 insertions(+), 13 deletions(-) create mode 100644 include/uapi/linux/vesa.h diff --git a/include/linux/console.h b/include/linux/console.h index f7c6b5fc3a36..860f82756c9c 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -18,6 +18,7 @@ #include #include #include +#include struct vc_data; struct console_font_op; @@ -520,12 +521,6 @@ void vcs_remove_sysfs(int index); */ extern atomic_t ignore_console_lock_warning; -/* VESA Blanking Levels */ -#define VESA_NO_BLANKING0 -#define VESA_VSYNC_SUSPEND 1 -#define VESA_HSYNC_SUSPEND 2 -#define VESA_POWERDOWN 3 - extern void console_init(void); /* For deferred console takeover */ diff --git a/include/uapi/linux/fb.h b/include/uapi/linux/fb.h index 3a49913d006c..cde8f173f566 100644 --- a/include/uapi/linux/fb.h +++ b/include/uapi/linux/fb.h @@ -4,6 +4,7 @@ #include #include +#include /* Definitions of frame buffers */ @@ -293,13 +294,6 @@ struct fb_con2fbmap { __u32 framebuffer; }; -/* VESA Blanking Levels */ -#define VESA_NO_BLANKING0 -#define VESA_VSYNC_SUSPEND 1 -#define VESA_HSYNC_SUSPEND 2 -#define VESA_POWERDOWN 3 - - enum { /* screen: unblanked, hsync: on, vsync: on */ FB_BLANK_UNBLANK = VESA_NO_BLANKING, diff --git a/include/uapi/linux/vesa.h b/include/uapi/linux/vesa.h new file mode 100644 index ..81947f5088cd --- /dev/null +++ b/include/uapi/linux/vesa.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _UAPI_LINUX_VESA_H +#define _UAPI_LINUX_VESA_H + +/* VESA Blanking Levels */ +enum vesa_blank_mode { + VESA_NO_BLANKING= 0, +#define VESA_NO_BLANKING VESA_NO_BLANKING + VESA_VSYNC_SUSPEND = 1, +#define VESA_VSYNC_SUSPEND VESA_VSYNC_SUSPEND + VESA_HSYNC_SUSPEND = 2, +#define VESA_HSYNC_SUSPEND VESA_HSYNC_SUSPEND + VESA_POWERDOWN = VESA_VSYNC_SUSPEND | VESA_HSYNC_SUSPEND, +#define VESA_POWERDOWN VESA_POWERDOWN + VESA_BLANK_MAX = VESA_POWERDOWN, +}; + +#endif -- 2.43.0
[PATCH v2 24/47] tty: vt: eliminate unneeded consw::con_putc() implementations
All these consw::con_putc() implementations do the same as consw::con_putcs() (only for one charattr) or even call consw::con_putcs() on their own. Drop them, as thanks to the new con_putc() helper in the previous patch, the console code performs this already -- exactly if consw::con_putc() is missing (NULL). Signed-off-by: Jiri Slaby (SUSE) Cc: Helge Deller Cc: "James E.J. Bottomley" Cc: Daniel Vetter Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linux-par...@vger.kernel.org --- drivers/video/console/mdacon.c | 6 -- drivers/video/console/sticon.c | 12 drivers/video/console/vgacon.c | 2 -- drivers/video/fbdev/core/fbcon.c | 9 - 4 files changed, 29 deletions(-) diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c index 2ff2c9394d40..01e779943c00 100644 --- a/drivers/video/console/mdacon.c +++ b/drivers/video/console/mdacon.c @@ -427,11 +427,6 @@ static inline u16 *mda_addr(unsigned int x, unsigned int y) return mda_vram_base + y * mda_num_columns + x; } -static void mdacon_putc(struct vc_data *c, int ch, int y, int x) -{ - scr_writew(mda_convert_attr(ch), mda_addr(x, y)); -} - static void mdacon_putcs(struct vc_data *c, const unsigned short *s, int count, int y, int x) { @@ -536,7 +531,6 @@ static const struct consw mda_con = { .con_init = mdacon_init, .con_deinit = mdacon_deinit, .con_clear =mdacon_clear, - .con_putc = mdacon_putc, .con_putcs =mdacon_putcs, .con_cursor = mdacon_cursor, .con_scroll = mdacon_scroll, diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index b1d972d9a31c..2f87b5909d0d 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -71,17 +71,6 @@ static const char *sticon_startup(void) return "STI console"; } -static void sticon_putc(struct vc_data *conp, int c, int ypos, int xpos) -{ -if (vga_is_gfx || console_blanked) - return; - -if (conp->vc_mode != KD_TEXT) - return; - -sti_putc(sticon_sti, c, ypos, xpos, font_data[conp->vc_num]); -} - static void sticon_putcs(struct vc_data *conp, const unsigned short *s, int count, int ypos, int xpos) { @@ -362,7 +351,6 @@ static const struct consw sti_con = { .con_init = sticon_init, .con_deinit = sticon_deinit, .con_clear = sticon_clear, - .con_putc = sticon_putc, .con_putcs = sticon_putcs, .con_cursor = sticon_cursor, .con_scroll = sticon_scroll, diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 85f29dec2c3d..4beab11f87eb 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -1193,7 +1193,6 @@ static bool vgacon_scroll(struct vc_data *c, unsigned int t, unsigned int b, static void vgacon_clear(struct vc_data *vc, unsigned int sy, unsigned int sx, unsigned int width) { } -static void vgacon_putc(struct vc_data *vc, int c, int ypos, int xpos) { } static void vgacon_putcs(struct vc_data *vc, const unsigned short *s, int count, int ypos, int xpos) { } @@ -1203,7 +1202,6 @@ const struct consw vga_con = { .con_init = vgacon_init, .con_deinit = vgacon_deinit, .con_clear = vgacon_clear, - .con_putc = vgacon_putc, .con_putcs = vgacon_putcs, .con_cursor = vgacon_cursor, .con_scroll = vgacon_scroll, diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 8a31a36483ea..38de0f8723aa 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -1292,14 +1292,6 @@ static void fbcon_putcs(struct vc_data *vc, const unsigned short *s, get_color(vc, info, scr_readw(s), 0)); } -static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos) -{ - unsigned short chr; - - scr_writew(c, &chr); - fbcon_putcs(vc, &chr, 1, ypos, xpos); -} - static void fbcon_clear_margins(struct vc_data *vc, int bottom_only) { struct fb_info *info = fbcon_info_from_console(vc->vc_num); @@ -3159,7 +3151,6 @@ static const struct consw fb_con = { .con_init = fbcon_init, .con_deinit = fbcon_deinit, .con_clear = fbcon_clear, - .con_putc = fbcon_putc, .con_putcs = fbcon_putcs, .con_cursor = fbcon_cursor, .con_scroll = fbcon_scroll, -- 2.43.0
[PATCH v2 38/47] tty: vt: change consw::con_set_origin() return type
The return value of consw::con_set_origin() is only true/false, meaining if vc->vc_origin is set to vc->vc_screenbuf or not. So switch the type and returned values accordingly. And document the hook. Signed-off-by: Jiri Slaby (SUSE) Cc: Helge Deller Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org --- drivers/video/console/vgacon.c | 8 include/linux/console.h| 5 - 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 4d1c8f5863af..7597f04b0dc7 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -65,7 +65,7 @@ static struct vgastate vgastate; * Interface used by the world */ -static int vgacon_set_origin(struct vc_data *c); +static bool vgacon_set_origin(struct vc_data *c); static struct uni_pagedict *vgacon_uni_pagedir; static int vgacon_refcount; @@ -1100,15 +1100,15 @@ static int vgacon_resize(struct vc_data *c, unsigned int width, return 0; } -static int vgacon_set_origin(struct vc_data *c) +static bool vgacon_set_origin(struct vc_data *c) { if (vga_is_gfx || /* We don't play origin tricks in graphic modes */ (console_blanked && !vga_palette_blanked)) /* Nor we write to blanked screens */ - return 0; + return false; c->vc_origin = c->vc_visible_origin = vga_vram_base; vga_set_mem_top(c); vga_rolled_over = 0; - return 1; + return true; } static void vgacon_save_screen(struct vc_data *c) diff --git a/include/linux/console.h b/include/linux/console.h index 6bb7e5e37ae4..82e4b554a801 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -55,6 +55,9 @@ enum vc_intensity; * @con_set_palette: sets the palette of the console to @table (optional) * @con_scrolldelta: the contents of the console should be scrolled by @lines. * Invoked by user. (optional) + * @con_set_origin: set origin (see &vc_data::vc_origin) of the @vc. If not + * provided or returns false, the origin is set to + * @vc->vc_screenbuf. (optional) */ struct consw { struct module *owner; @@ -87,7 +90,7 @@ struct consw { void(*con_set_palette)(struct vc_data *vc, const unsigned char *table); void(*con_scrolldelta)(struct vc_data *vc, int lines); - int (*con_set_origin)(struct vc_data *vc); + bool(*con_set_origin)(struct vc_data *vc); void(*con_save_screen)(struct vc_data *vc); u8 (*con_build_attr)(struct vc_data *vc, u8 color, enum vc_intensity intensity, -- 2.43.0
[PATCH v2 27/47] consoles: use if instead of switch-case in consw::con_cursor()
This is only a preparation for the following cleanup patch to make it easier. Provided CM_ERASE is the only different, use 'if' instead of 'switch+case' in all those. Signed-off-by: Jiri Slaby (SUSE) Cc: Helge Deller Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org --- drivers/video/console/newport_con.c | 26 +--- drivers/video/console/sticon.c | 27 ++-- drivers/video/console/vgacon.c | 66 + 3 files changed, 53 insertions(+), 66 deletions(-) diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index 5e65ee0b7c07..f852717b88f0 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -443,24 +443,20 @@ static void newport_cursor(struct vc_data *vc, int mode) unsigned short treg; int xcurs, ycurs; - switch (mode) { - case CM_ERASE: - treg = newport_vc2_get(npregs, VC2_IREG_CONTROL); - newport_vc2_set(npregs, VC2_IREG_CONTROL, - (treg & ~(VC2_CTRL_ECDISP))); - break; + treg = newport_vc2_get(npregs, VC2_IREG_CONTROL); - case CM_MOVE: - case CM_DRAW: - treg = newport_vc2_get(npregs, VC2_IREG_CONTROL); + if (mode == CM_ERASE) { newport_vc2_set(npregs, VC2_IREG_CONTROL, - (treg | VC2_CTRL_ECDISP)); - xcurs = (vc->vc_pos - vc->vc_visible_origin) / 2; - ycurs = ((xcurs / vc->vc_cols) << 4) + 31; - xcurs = ((xcurs % vc->vc_cols) << 3) + xcurs_correction; - newport_vc2_set(npregs, VC2_IREG_CURSX, xcurs); - newport_vc2_set(npregs, VC2_IREG_CURSY, ycurs); + (treg & ~(VC2_CTRL_ECDISP))); + return; } + + newport_vc2_set(npregs, VC2_IREG_CONTROL, (treg | VC2_CTRL_ECDISP)); + xcurs = (vc->vc_pos - vc->vc_visible_origin) / 2; + ycurs = ((xcurs / vc->vc_cols) << 4) + 31; + xcurs = ((xcurs % vc->vc_cols) << 3) + xcurs_correction; + newport_vc2_set(npregs, VC2_IREG_CURSX, xcurs); + newport_vc2_set(npregs, VC2_IREG_CURSY, ycurs); } static int newport_switch(struct vc_data *vc) diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index 906da1fde7c8..42480874db00 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -95,23 +95,20 @@ static void sticon_cursor(struct vc_data *conp, int mode) return; car1 = conp->vc_screenbuf[conp->state.x + conp->state.y * conp->vc_cols]; -switch (mode) { -case CM_ERASE: +if (mode == CM_ERASE) { sti_putc(sticon_sti, car1, conp->state.y, conp->state.x, font_data[conp->vc_num]); - break; -case CM_MOVE: -case CM_DRAW: - switch (CUR_SIZE(conp->vc_cursor_type)) { - case CUR_UNDERLINE: - case CUR_LOWER_THIRD: - case CUR_LOWER_HALF: - case CUR_TWO_THIRDS: - case CUR_BLOCK: - sti_putc(sticon_sti, (car1 & 255) + (0 << 8) + (7 << 11), -conp->state.y, conp->state.x, font_data[conp->vc_num]); - break; - } + return; +} + +switch (CUR_SIZE(conp->vc_cursor_type)) { +case CUR_UNDERLINE: +case CUR_LOWER_THIRD: +case CUR_LOWER_HALF: +case CUR_TWO_THIRDS: +case CUR_BLOCK: + sti_putc(sticon_sti, (car1 & 255) + (0 << 8) + (7 << 11), +conp->state.y, conp->state.x, font_data[conp->vc_num]); break; } } diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index aa0589085847..82d01a9ccd6d 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -514,47 +514,41 @@ static void vgacon_cursor(struct vc_data *c, int mode) c_height = c->vc_cell_height; - switch (mode) { - case CM_ERASE: - write_vga(14, (c->vc_pos - vga_vram_base) / 2); + write_vga(14, (c->vc_pos - vga_vram_base) / 2); + + if (mode == CM_ERASE) { if (vga_video_type >= VIDEO_TYPE_VGAC) vgacon_set_cursor_size(31, 30); else vgacon_set_cursor_size(31, 31); - break; + return; + } - case CM_MOVE: - case CM_DRAW: - write_vga(14, (c->vc_pos - vga_vram_base) / 2); - switch (CUR_SIZE(c->vc_cursor_type)) { - case CUR_UNDERLINE: - vgacon_set_cursor_size(c_height - - (c_height < 10 ? 2 : 3), - c_height - - (c_height < 10 ? 1 : 2)); - break; - case CUR_TWO_THIRDS: - vgacon_set_cursor_size(c_height / 3, c_height - -
[PATCH v2 37/47] tty: vt: make consw::con_font_default()'s name const
It's a name after all and that is not supposed to be changed. So make it const to make this obvious. Signed-off-by: Jiri Slaby (SUSE) Cc: "James E.J. Bottomley" Cc: Daniel Vetter Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linux-par...@vger.kernel.org --- drivers/video/console/newport_con.c | 3 ++- drivers/video/console/sticon.c | 3 ++- drivers/video/fbdev/core/fbcon.c| 3 ++- include/linux/console.h | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index 4203bd5fd0a1..a51cfc1d560e 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -564,7 +564,8 @@ static int newport_set_def_font(int unit, struct console_font *op) return 0; } -static int newport_font_default(struct vc_data *vc, struct console_font *op, char *name) +static int newport_font_default(struct vc_data *vc, struct console_font *op, + const char *name) { return newport_set_def_font(vc->vc_num, op); } diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index 710201fb8ce4..4c7b4959a1aa 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -246,7 +246,8 @@ static int sticon_set_font(struct vc_data *vc, const struct console_font *op, return 0; } -static int sticon_font_default(struct vc_data *vc, struct console_font *op, char *name) +static int sticon_font_default(struct vc_data *vc, struct console_font *op, + const char *name) { sticon_set_def_font(vc->vc_num); diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 62474630c4d4..657160eec0a5 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -2533,7 +2533,8 @@ static int fbcon_set_font(struct vc_data *vc, const struct console_font *font, return fbcon_do_set_font(vc, font->width, font->height, charcount, new_data, 1); } -static int fbcon_set_def_font(struct vc_data *vc, struct console_font *font, char *name) +static int fbcon_set_def_font(struct vc_data *vc, struct console_font *font, + const char *name) { struct fb_info *info = fbcon_info_from_console(vc->vc_num); const struct font_desc *f; diff --git a/include/linux/console.h b/include/linux/console.h index 0a9f4cbdde83..6bb7e5e37ae4 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -81,7 +81,7 @@ struct consw { int (*con_font_get)(struct vc_data *vc, struct console_font *font, unsigned int vpitch); int (*con_font_default)(struct vc_data *vc, - struct console_font *font, char *name); + struct console_font *font, const char *name); int (*con_resize)(struct vc_data *vc, unsigned int width, unsigned int height, bool from_user); void(*con_set_palette)(struct vc_data *vc, -- 2.43.0
[PATCH v2 30/47] tty: vt: make consw::con_switch() return a bool
The non-zero (true) return value from consw::con_switch() means a redraw is needed. So make this return type a bool explicitly instead of int. The latter might imply that -Eerrors are expected. They are not. And document the hook. Signed-off-by: Jiri Slaby (SUSE) Cc: Helge Deller Cc: "James E.J. Bottomley" Cc: Daniel Vetter Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linux-par...@vger.kernel.org --- drivers/tty/vt/vt.c | 2 +- drivers/video/console/dummycon.c| 4 ++-- drivers/video/console/mdacon.c | 4 ++-- drivers/video/console/newport_con.c | 4 ++-- drivers/video/console/sticon.c | 4 ++-- drivers/video/console/vgacon.c | 4 ++-- drivers/video/fbdev/core/fbcon.c| 6 +++--- include/linux/console.h | 4 +++- 8 files changed, 17 insertions(+), 15 deletions(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index e4edcaf9d0a3..fd868046f586 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -970,7 +970,7 @@ void redraw_screen(struct vc_data *vc, int is_switch) } if (redraw) { - int update; + bool update; int old_was_color = vc->vc_can_do_color; set_origin(vc); diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c index 1171e27edef7..c8d5aa0e3ed0 100644 --- a/drivers/video/console/dummycon.c +++ b/drivers/video/console/dummycon.c @@ -122,9 +122,9 @@ static bool dummycon_scroll(struct vc_data *vc, unsigned int top, return false; } -static int dummycon_switch(struct vc_data *vc) +static bool dummycon_switch(struct vc_data *vc) { - return 0; + return false; } /* diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c index bc851a1d9f4d..4485ef923bb3 100644 --- a/drivers/video/console/mdacon.c +++ b/drivers/video/console/mdacon.c @@ -446,9 +446,9 @@ static void mdacon_clear(struct vc_data *c, unsigned int y, unsigned int x, scr_memsetw(dest, eattr, width * 2); } -static int mdacon_switch(struct vc_data *c) +static bool mdacon_switch(struct vc_data *c) { - return 1; /* redrawing needed */ + return true;/* redrawing needed */ } static int mdacon_blank(struct vc_data *c, int blank, int mode_switch) diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index e35406dea7c7..039d1c9937d2 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -459,7 +459,7 @@ static void newport_cursor(struct vc_data *vc, bool enable) newport_vc2_set(npregs, VC2_IREG_CURSY, ycurs); } -static int newport_switch(struct vc_data *vc) +static bool newport_switch(struct vc_data *vc) { static int logo_drawn = 0; @@ -473,7 +473,7 @@ static int newport_switch(struct vc_data *vc) } } - return 1; + return true; } static int newport_blank(struct vc_data *c, int blank, int mode_switch) diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index 786e1b3a98ea..f3bb48a0e980 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -293,9 +293,9 @@ static void sticon_clear(struct vc_data *conp, unsigned int sy, unsigned int sx, conp->vc_video_erase_char, font_data[conp->vc_num]); } -static int sticon_switch(struct vc_data *conp) +static bool sticon_switch(struct vc_data *conp) { -return 1; /* needs refreshing */ +return true; /* needs refreshing */ } static int sticon_blank(struct vc_data *c, int blank, int mode_switch) diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index d93eb15da435..f89eb53c0b79 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -614,7 +614,7 @@ static void vgacon_doresize(struct vc_data *c, raw_spin_unlock_irqrestore(&vga_lock, flags); } -static int vgacon_switch(struct vc_data *c) +static bool vgacon_switch(struct vc_data *c) { int x = c->vc_cols * VGA_FONTWIDTH; int y = c->vc_rows * c->vc_cell_height; @@ -643,7 +643,7 @@ static int vgacon_switch(struct vc_data *c) vgacon_doresize(c, c->vc_cols, c->vc_rows); } - return 0; /* Redrawing not needed */ + return false; /* Redrawing not needed */ } static void vga_set_palette(struct vc_data *vc, const unsigned char *table) diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index c1765a6ef490..d5d924225209 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -2056,7 +2056,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width, return 0; } -static int fbcon_switch(struct vc_data *vc) +static bool fbcon_switch(struct vc_data *vc) { struct fb_info *info, *old_info = NULL; struct fbcon_ops *ops; @@ -2178,9 +217
[PATCH v2 25/47] tty: vt: sanitize consw::con_putc() parameters
Make parameters of consw::con_putc() saner: * x and y are unsigned now, as they cannot be negative, and * ca is made u16, as it is composed of two 8bit values (character and attribute). See the con_putcs() hook, u16/ushort is worked on there. And document the hook. Signed-off-by: Jiri Slaby (SUSE) Cc: Helge Deller Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org --- drivers/video/console/dummycon.c| 6 -- drivers/video/console/newport_con.c | 4 ++-- include/linux/console.h | 5 - 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c index 0a69d5c216ee..1874beed0325 100644 --- a/drivers/video/console/dummycon.c +++ b/drivers/video/console/dummycon.c @@ -50,7 +50,8 @@ void dummycon_unregister_output_notifier(struct notifier_block *nb) raw_notifier_chain_unregister(&dummycon_output_nh, nb); } -static void dummycon_putc(struct vc_data *vc, int c, int ypos, int xpos) +static void dummycon_putc(struct vc_data *vc, u16 c, unsigned int y, + unsigned int x) { WARN_CONSOLE_UNLOCKED(); @@ -84,7 +85,8 @@ static int dummycon_blank(struct vc_data *vc, int blank, int mode_switch) return 1; } #else -static void dummycon_putc(struct vc_data *vc, int c, int ypos, int xpos) { } +static void dummycon_putc(struct vc_data *vc, u16 c, unsigned int y, + unsigned int x) { } static void dummycon_putcs(struct vc_data *vc, const unsigned short *s, int count, int ypos, int xpos) { } static int dummycon_blank(struct vc_data *vc, int blank, int mode_switch) diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index 55c6106b3507..9b5c0118873e 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -367,8 +367,8 @@ static void newport_clear(struct vc_data *vc, unsigned int sy, unsigned int sx, } } -static void newport_putc(struct vc_data *vc, int charattr, int ypos, -int xpos) +static void newport_putc(struct vc_data *vc, u16 charattr, unsigned int ypos, +unsigned int xpos) { unsigned char *p; diff --git a/include/linux/console.h b/include/linux/console.h index 8fd96a5fca5f..92d57e5b3009 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -39,6 +39,8 @@ enum vc_intensity; * @con_init: initialize the console on @vc. @init is true for the very first * call on this @vc. * @con_clear: erase @count characters at [@x, @y] on @vc. @count >= 1. + * @con_putc: emit one character with attributes @ca to [@x, @y] on @vc. + * (optional -- @con_putcs would be called instead) * @con_scroll: move lines from @top to @bottom in direction @dir by @lines. * Return true if no generic handling should be done. * Invoked by csi_M and printing to the console. @@ -53,7 +55,8 @@ struct consw { void(*con_deinit)(struct vc_data *vc); void(*con_clear)(struct vc_data *vc, unsigned int y, unsigned int x, unsigned int count); - void(*con_putc)(struct vc_data *vc, int c, int ypos, int xpos); + void(*con_putc)(struct vc_data *vc, u16 ca, unsigned int y, + unsigned int x); void(*con_putcs)(struct vc_data *vc, const unsigned short *s, int count, int ypos, int xpos); void(*con_cursor)(struct vc_data *vc, int mode); -- 2.43.0
[PATCH v2 34/47] tty: vt: use enum constants for VESA blanking modes
Use the new enum for VESA constants. This improves type checking in consw::con_blank(). Signed-off-by: Jiri Slaby (SUSE) Cc: Helge Deller Cc: "James E.J. Bottomley" Cc: Daniel Vetter Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linux-par...@vger.kernel.org --- Notes: [v2] the enum is added earlier, so reword and rebase drivers/tty/vt/vt.c | 4 ++-- drivers/video/console/dummycon.c| 6 -- drivers/video/console/mdacon.c | 3 ++- drivers/video/console/newport_con.c | 3 ++- drivers/video/console/sticon.c | 3 ++- drivers/video/console/vgacon.c | 7 --- drivers/video/fbdev/core/fbcon.c| 3 ++- include/linux/console.h | 3 ++- 8 files changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 0d5d7b5074a4..de9148094c2d 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -175,7 +175,7 @@ int do_poke_blanked_console; int console_blanked; EXPORT_SYMBOL(console_blanked); -static int vesa_blank_mode; /* 0:none 1:suspendV 2:suspendH 3:powerdown */ +static enum vesa_blank_mode vesa_blank_mode; static int vesa_off_interval; static int blankinterval; core_param(consoleblank, blankinterval, int, 0444); @@ -4320,7 +4320,7 @@ static int set_vesa_blanking(u8 __user *mode_user) return -EFAULT; console_lock(); - vesa_blank_mode = (mode < 4) ? mode : VESA_NO_BLANKING; + vesa_blank_mode = (mode <= VESA_BLANK_MAX) ? mode : VESA_NO_BLANKING; console_unlock(); return 0; diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c index c8d5aa0e3ed0..d86c1d798690 100644 --- a/drivers/video/console/dummycon.c +++ b/drivers/video/console/dummycon.c @@ -79,7 +79,8 @@ static void dummycon_putcs(struct vc_data *vc, const u16 *s, unsigned int count, raw_notifier_call_chain(&dummycon_output_nh, 0, NULL); } -static int dummycon_blank(struct vc_data *vc, int blank, int mode_switch) +static int dummycon_blank(struct vc_data *vc, enum vesa_blank_mode blank, + int mode_switch) { /* Redraw, so that we get putc(s) for output done while blanked */ return 1; @@ -89,7 +90,8 @@ static void dummycon_putc(struct vc_data *vc, u16 c, unsigned int y, unsigned int x) { } static void dummycon_putcs(struct vc_data *vc, const u16 *s, unsigned int count, unsigned int ypos, unsigned int xpos) { } -static int dummycon_blank(struct vc_data *vc, int blank, int mode_switch) +static int dummycon_blank(struct vc_data *vc, enum vesa_blank_mode blank, + int mode_switch) { return 0; } diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c index 4485ef923bb3..63e3ce678aab 100644 --- a/drivers/video/console/mdacon.c +++ b/drivers/video/console/mdacon.c @@ -451,7 +451,8 @@ static bool mdacon_switch(struct vc_data *c) return true;/* redrawing needed */ } -static int mdacon_blank(struct vc_data *c, int blank, int mode_switch) +static int mdacon_blank(struct vc_data *c, enum vesa_blank_mode blank, + int mode_switch) { if (mda_type == TYPE_MDA) { if (blank) diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index ad3a09142770..38437a53b7f1 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -476,7 +476,8 @@ static bool newport_switch(struct vc_data *vc) return true; } -static int newport_blank(struct vc_data *c, int blank, int mode_switch) +static int newport_blank(struct vc_data *c, enum vesa_blank_mode blank, +int mode_switch) { unsigned short treg; diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index 817b89c45e81..e9d5d1f92883 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -298,7 +298,8 @@ static bool sticon_switch(struct vc_data *conp) return true; /* needs refreshing */ } -static int sticon_blank(struct vc_data *c, int blank, int mode_switch) +static int sticon_blank(struct vc_data *c, enum vesa_blank_mode blank, + int mode_switch) { if (blank == VESA_NO_BLANKING) { if (mode_switch) diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 02eccd9b3542..84f3682704c7 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -81,7 +81,7 @@ static unsigned int vga_video_num_lines; /* Number of text lines */ static boolvga_can_do_color; /* Do we support colors? */ static unsigned intvga_default_font_height __read_mostly; /* Height of default screen font */ static unsigned char vga_video_type __read_mostly; /* Card type */ -static int vga_vesa_
[PATCH v2 35/47] tty: vt: make types around consw::con_blank() bool
Both the mode_switch parameter and the return value (a redraw needed) are true/false. So switch them to bool, so that users won't return -Eerrors or anything else. And document the hook. Signed-off-by: Jiri Slaby (SUSE) Cc: Helge Deller Cc: "James E.J. Bottomley" Cc: Daniel Vetter Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linux-par...@vger.kernel.org --- drivers/video/console/dummycon.c| 12 ++-- drivers/video/console/mdacon.c | 8 drivers/video/console/newport_con.c | 7 --- drivers/video/console/sticon.c | 9 + drivers/video/console/vgacon.c | 4 ++-- drivers/video/fbdev/core/fbcon.c| 6 +++--- include/linux/console.h | 7 +-- 7 files changed, 29 insertions(+), 24 deletions(-) diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c index d86c1d798690..139049368fdc 100644 --- a/drivers/video/console/dummycon.c +++ b/drivers/video/console/dummycon.c @@ -79,21 +79,21 @@ static void dummycon_putcs(struct vc_data *vc, const u16 *s, unsigned int count, raw_notifier_call_chain(&dummycon_output_nh, 0, NULL); } -static int dummycon_blank(struct vc_data *vc, enum vesa_blank_mode blank, - int mode_switch) +static bool dummycon_blank(struct vc_data *vc, enum vesa_blank_mode blank, + bool mode_switch) { /* Redraw, so that we get putc(s) for output done while blanked */ - return 1; + return true; } #else static void dummycon_putc(struct vc_data *vc, u16 c, unsigned int y, unsigned int x) { } static void dummycon_putcs(struct vc_data *vc, const u16 *s, unsigned int count, unsigned int ypos, unsigned int xpos) { } -static int dummycon_blank(struct vc_data *vc, enum vesa_blank_mode blank, - int mode_switch) +static bool dummycon_blank(struct vc_data *vc, enum vesa_blank_mode blank, + bool mode_switch) { - return 0; + return false; } #endif diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c index 63e3ce678aab..c0e1f4554a44 100644 --- a/drivers/video/console/mdacon.c +++ b/drivers/video/console/mdacon.c @@ -451,8 +451,8 @@ static bool mdacon_switch(struct vc_data *c) return true;/* redrawing needed */ } -static int mdacon_blank(struct vc_data *c, enum vesa_blank_mode blank, - int mode_switch) +static bool mdacon_blank(struct vc_data *c, enum vesa_blank_mode blank, +bool mode_switch) { if (mda_type == TYPE_MDA) { if (blank) @@ -460,14 +460,14 @@ static int mdacon_blank(struct vc_data *c, enum vesa_blank_mode blank, mda_convert_attr(c->vc_video_erase_char), c->vc_screenbuf_size); /* Tell console.c that it has to restore the screen itself */ - return 1; + return true; } else { if (blank) outb_p(0x00, mda_mode_port);/* disable video */ else outb_p(MDA_MODE_VIDEO_EN | MDA_MODE_BLINK_EN, mda_mode_port); - return 0; + return false; } } diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index 38437a53b7f1..dbb31bf87bf1 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -476,8 +476,8 @@ static bool newport_switch(struct vc_data *vc) return true; } -static int newport_blank(struct vc_data *c, enum vesa_blank_mode blank, -int mode_switch) +static bool newport_blank(struct vc_data *c, enum vesa_blank_mode blank, + bool mode_switch) { unsigned short treg; @@ -492,7 +492,8 @@ static int newport_blank(struct vc_data *c, enum vesa_blank_mode blank, newport_vc2_set(npregs, VC2_IREG_CONTROL, (treg & ~(VC2_CTRL_EDISP))); } - return 1; + + return true; } static int newport_set_font(int unit, struct console_font *op, unsigned int vpitch) diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index e9d5d1f92883..cbb9ef438214 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -298,19 +298,20 @@ static bool sticon_switch(struct vc_data *conp) return true; /* needs refreshing */ } -static int sticon_blank(struct vc_data *c, enum vesa_blank_mode blank, - int mode_switch) +static bool sticon_blank(struct vc_data *c, enum vesa_blank_mode blank, +bool mode_switch) { if (blank == VESA_NO_BLANKING) { if (mode_switch) vga_is_gfx = 0; - return 1; + return true; }
[PATCH v2 36/47] tty: vt: make font of consw::con_font_set() const
Provided the font parameter of consw::con_font_set() is not supposed to be changed, make it const. Signed-off-by: Jiri Slaby (SUSE) Cc: Helge Deller Cc: "James E.J. Bottomley" Cc: Daniel Vetter Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linux-par...@vger.kernel.org --- drivers/tty/vt/vt.c | 2 +- drivers/video/console/newport_con.c | 5 +++-- drivers/video/console/sticon.c | 4 ++-- drivers/video/console/vgacon.c | 2 +- drivers/video/fbdev/core/fbcon.c| 2 +- include/linux/console.h | 5 +++-- 6 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index de9148094c2d..0ac537f82f7a 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -4625,7 +4625,7 @@ static int con_font_get(struct vc_data *vc, struct console_font_op *op) return rc; } -static int con_font_set(struct vc_data *vc, struct console_font_op *op) +static int con_font_set(struct vc_data *vc, const struct console_font_op *op) { struct console_font font; int rc = -EINVAL; diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index dbb31bf87bf1..4203bd5fd0a1 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -496,7 +496,8 @@ static bool newport_blank(struct vc_data *c, enum vesa_blank_mode blank, return true; } -static int newport_set_font(int unit, struct console_font *op, unsigned int vpitch) +static int newport_set_font(int unit, const struct console_font *op, + unsigned int vpitch) { int w = op->width; int h = op->height; @@ -568,7 +569,7 @@ static int newport_font_default(struct vc_data *vc, struct console_font *op, cha return newport_set_def_font(vc->vc_num, op); } -static int newport_font_set(struct vc_data *vc, struct console_font *font, +static int newport_font_set(struct vc_data *vc, const struct console_font *font, unsigned int vpitch, unsigned int flags) { return newport_set_font(vc->vc_num, font, vpitch); diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index cbb9ef438214..710201fb8ce4 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -153,7 +153,7 @@ static void sticon_set_def_font(int unit) } } -static int sticon_set_font(struct vc_data *vc, struct console_font *op, +static int sticon_set_font(struct vc_data *vc, const struct console_font *op, unsigned int vpitch) { struct sti_struct *sti = sticon_sti; @@ -253,7 +253,7 @@ static int sticon_font_default(struct vc_data *vc, struct console_font *op, char return 0; } -static int sticon_font_set(struct vc_data *vc, struct console_font *font, +static int sticon_font_set(struct vc_data *vc, const struct console_font *font, unsigned int vpitch, unsigned int flags) { return sticon_set_font(vc, font, vpitch); diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index c9a22118102f..4d1c8f5863af 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -1039,7 +1039,7 @@ static int vgacon_adjust_height(struct vc_data *vc, unsigned fontheight) return 0; } -static int vgacon_font_set(struct vc_data *c, struct console_font *font, +static int vgacon_font_set(struct vc_data *c, const struct console_font *font, unsigned int vpitch, unsigned int flags) { unsigned charcount = font->charcount; diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index eee2adf5c682..62474630c4d4 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -2460,7 +2460,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount, * but lets not assume that, since charcount of 512 is small for unicode support. */ -static int fbcon_set_font(struct vc_data *vc, struct console_font *font, +static int fbcon_set_font(struct vc_data *vc, const struct console_font *font, unsigned int vpitch, unsigned int flags) { struct fb_info *info = fbcon_info_from_console(vc->vc_num); diff --git a/include/linux/console.h b/include/linux/console.h index 6392bcd2fe7c..0a9f4cbdde83 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -75,8 +75,9 @@ struct consw { bool(*con_switch)(struct vc_data *vc); bool(*con_blank)(struct vc_data *vc, enum vesa_blank_mode blank, bool mode_switch); - int (*con_font_set)(struct vc_data *vc, struct console_font *font, - unsigned int vpitch, unsigned int flags); + int (*con_font_set)(struct vc_data *vc, + const struct console_font *font, +
[PATCH v2 39/47] fbcon: remove consw::con_screen_pos()
fbcon_screen_pos() performs the same as the default implementation. The only difference in the default implementation is that is considers both vc->vc_origin and vc->vc_visible_origin. But given fbcon's softscroll code was already removed in commit 50145474f6ef (fbcon: remove soft scrollback code), both are always the same. So remove fbcon_screen_pos() too. Signed-off-by: Jiri Slaby (SUSE) Cc: Daniel Vetter Cc: Helge Deller Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org --- drivers/video/fbdev/core/fbcon.c | 6 -- 1 file changed, 6 deletions(-) diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 657160eec0a5..2166ea1a5430 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -2593,11 +2593,6 @@ static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table) fb_set_cmap(&palette_cmap, info); } -static u16 *fbcon_screen_pos(const struct vc_data *vc, int offset) -{ - return (u16 *) (vc->vc_origin + offset); -} - static unsigned long fbcon_getxy(struct vc_data *vc, unsigned long pos, int *px, int *py) { @@ -3162,7 +3157,6 @@ static const struct consw fb_con = { .con_font_default = fbcon_set_def_font, .con_set_palette= fbcon_set_palette, .con_invert_region = fbcon_invert_region, - .con_screen_pos = fbcon_screen_pos, .con_getxy = fbcon_getxy, .con_resize = fbcon_resize, .con_debug_enter= fbcon_debug_enter, -- 2.43.0
[PATCH v2 42/47] fbcon: remove fbcon_getxy()
Again, fbcon_getxy() is the same as the default implementation since the softscroll removal in commit 50145474f6ef (fbcon: remove soft scrollback code). Drop that. Signed-off-by: Jiri Slaby (SUSE) Cc: Daniel Vetter Cc: Helge Deller Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org --- drivers/video/fbdev/core/fbcon.c | 25 - 1 file changed, 25 deletions(-) diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 2166ea1a5430..9c2962900d13 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -2593,30 +2593,6 @@ static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table) fb_set_cmap(&palette_cmap, info); } -static unsigned long fbcon_getxy(struct vc_data *vc, unsigned long pos, -int *px, int *py) -{ - unsigned long ret; - int x, y; - - if (pos >= vc->vc_origin && pos < vc->vc_scr_end) { - unsigned long offset = (pos - vc->vc_origin) / 2; - - x = offset % vc->vc_cols; - y = offset / vc->vc_cols; - ret = pos + (vc->vc_cols - x) * 2; - } else { - /* Should not happen */ - x = y = 0; - ret = vc->vc_origin; - } - if (px) - *px = x; - if (py) - *py = y; - return ret; -} - /* As we might be inside of softback, we may work with non-contiguous buffer, that's why we have to use a separate routine. */ static void fbcon_invert_region(struct vc_data *vc, u16 * p, int cnt) @@ -3157,7 +3133,6 @@ static const struct consw fb_con = { .con_font_default = fbcon_set_def_font, .con_set_palette= fbcon_set_palette, .con_invert_region = fbcon_invert_region, - .con_getxy = fbcon_getxy, .con_resize = fbcon_resize, .con_debug_enter= fbcon_debug_enter, .con_debug_leave= fbcon_debug_leave, -- 2.43.0
Re: [Linaro-mm-sig] Re: [PATCH v5 3/8] dmaengine: Add API function dmaengine_prep_slave_dma_vec()
Hi Paul, On 08-01-24, 13:20, Paul Cercueil wrote: > Hi Vinod, > > Le jeudi 21 décembre 2023 à 20:44 +0530, Vinod Koul a écrit : > > On 19-12-23, 18:50, Paul Cercueil wrote: > > > This function can be used to initiate a scatter-gather DMA > > > transfer, > > > where the address and size of each segment is located in one entry > > > of > > > the dma_vec array. > > > > > > The major difference with dmaengine_prep_slave_sg() is that it > > > supports > > > specifying the lengths of each DMA transfer; as trying to override > > > the > > > length of the transfer with dmaengine_prep_slave_sg() is a very > > > tedious > > > process. The introduction of a new API function is also justified > > > by the > > > fact that scatterlists are on their way out. > > > > > > Note that dmaengine_prep_interleaved_dma() is not helpful either in > > > that > > > case, as it assumes that the address of each segment will be higher > > > than > > > the one of the previous segment, which we just cannot guarantee in > > > case > > > of a scatter-gather transfer. > > > > > > Signed-off-by: Paul Cercueil > > > > > > --- > > > v3: New patch > > > > > > v5: Replace with function dmaengine_prep_slave_dma_vec(), and > > > struct > > > 'dma_vec'. > > > Note that at some point we will need to support cyclic > > > transfers > > > using dmaengine_prep_slave_dma_vec(). Maybe with a new "flags" > > > parameter to the function? > > > --- > > > include/linux/dmaengine.h | 25 + > > > 1 file changed, 25 insertions(+) > > > > > > diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h > > > index 3df70d6131c8..ee5931ddb42f 100644 > > > --- a/include/linux/dmaengine.h > > > +++ b/include/linux/dmaengine.h > > > @@ -160,6 +160,16 @@ struct dma_interleaved_template { > > > struct data_chunk sgl[]; > > > }; > > > > > > +/** > > > + * struct dma_vec - DMA vector > > > + * @addr: Bus address of the start of the vector > > > + * @len: Length in bytes of the DMA vector > > > + */ > > > +struct dma_vec { > > > + dma_addr_t addr; > > > + size_t len; > > > +}; > > I don't want to be pushy, but I'd like to know how to solve this now, > otherwise I'll just send the same patches for my v6. > > > so you want to transfer multiple buffers, right? why not use > > dmaengine_prep_slave_sg(). If there is reason for not using that one? > > The reason is that we want to have the possibility to transfer less > than the total size of the scatterlist, and that's currently very hard > to do - scatterlists were designed to not be tampered with. > > Christian König then suggested to introduce a "dma_vec" which had been > on his TODO list for a while now. Yeah for this interleaved seems overkill. Lets go with this api. I would suggest change the name of the API replacing slave with peripheral though -- ~Vinod
Re: (subset) [PATCH v2 1/2] ARM: dts: exynos4212-tab3: add samsung,invert-vclk flag to fimd
On Fri, 05 Jan 2024 07:53:01 +0100, Artur Weber wrote: > After more investigation, I've found that it's not the panel driver > config that needs to be modified to invert the data polarity, but > the FIMD config. > > Add the missing invert-vclk option that is required to get the display > to work correctly. > > [...] Applied, thanks! [1/2] ARM: dts: exynos4212-tab3: add samsung,invert-vclk flag to fimd https://git.kernel.org/krzk/linux/c/eab4f56d3e75dad697acf8dc2c8be3c341d6c63e Best regards, -- Krzysztof Kozlowski
[PATCH v3] drm/stm: Avoid use-after-free issues with crtc and plane
ltdc_load() calls functions drm_crtc_init_with_planes(), drm_universal_plane_init() and drm_encoder_init(). These functions should not be called with parameters allocated with devm_kzalloc() to avoid use-after-free issues [1]. Use allocations managed by the DRM framework. Found by Linux Verification Center (linuxtesting.org). [1] https://lore.kernel.org/lkml/u366i76e3qhh3ra5oxrtngjtm2u5lterkekcz6y2jkndhuxzli@diujon4h7qwb/ Signed-off-by: Katya Orlova --- v3: style problems v2: use allocations managed by the DRM as Raphael Gallais-Pou suggested. Also add a fix for encoder. drivers/gpu/drm/stm/drv.c | 3 +- drivers/gpu/drm/stm/ltdc.c | 69 +- 2 files changed, 18 insertions(+), 54 deletions(-) diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c index e8523abef27a..152bec2c0238 100644 --- a/drivers/gpu/drm/stm/drv.c +++ b/drivers/gpu/drm/stm/drv.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "ltdc.h" @@ -75,7 +76,7 @@ static int drv_load(struct drm_device *ddev) DRM_DEBUG("%s\n", __func__); - ldev = devm_kzalloc(ddev->dev, sizeof(*ldev), GFP_KERNEL); + ldev = drmm_kzalloc(ddev, sizeof(*ldev), GFP_KERNEL); if (!ldev) return -ENOMEM; diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c index 5576fdae4962..e050b519ad38 100644 --- a/drivers/gpu/drm/stm/ltdc.c +++ b/drivers/gpu/drm/stm/ltdc.c @@ -36,6 +36,7 @@ #include #include #include +#include #include @@ -1199,7 +1200,6 @@ static void ltdc_crtc_atomic_print_state(struct drm_printer *p, } static const struct drm_crtc_funcs ltdc_crtc_funcs = { - .destroy = drm_crtc_cleanup, .set_config = drm_atomic_helper_set_config, .page_flip = drm_atomic_helper_page_flip, .reset = drm_atomic_helper_crtc_reset, @@ -1212,7 +1212,6 @@ static const struct drm_crtc_funcs ltdc_crtc_funcs = { }; static const struct drm_crtc_funcs ltdc_crtc_with_crc_support_funcs = { - .destroy = drm_crtc_cleanup, .set_config = drm_atomic_helper_set_config, .page_flip = drm_atomic_helper_page_flip, .reset = drm_atomic_helper_crtc_reset, @@ -1545,7 +1544,6 @@ static void ltdc_plane_atomic_print_state(struct drm_printer *p, static const struct drm_plane_funcs ltdc_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, - .destroy = drm_plane_cleanup, .reset = drm_atomic_helper_plane_reset, .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, @@ -1572,7 +1570,6 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev, const u64 *modifiers = ltdc_format_modifiers; u32 lofs = index * LAY_OFS; u32 val; - int ret; /* Allocate the biggest size according to supported color formats */ formats = devm_kzalloc(dev, (ldev->caps.pix_fmt_nb + @@ -1613,14 +1610,10 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev, } } - plane = devm_kzalloc(dev, sizeof(*plane), GFP_KERNEL); - if (!plane) - return NULL; - - ret = drm_universal_plane_init(ddev, plane, possible_crtcs, -caps.ycbcr_input) { @@ -1643,15 +1636,6 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev, return plane; } -static void ltdc_plane_destroy_all(struct drm_device *ddev) -{ - struct drm_plane *plane, *plane_temp; - - list_for_each_entry_safe(plane, plane_temp, -&ddev->mode_config.plane_list, head) - drm_plane_cleanup(plane); -} - static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc) { struct ltdc_device *ldev = ddev->dev_private; @@ -1677,14 +1661,14 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc) /* Init CRTC according to its hardware features */ if (ldev->caps.crc) - ret = drm_crtc_init_with_planes(ddev, crtc, primary, NULL, + ret = drmm_crtc_init_with_planes(ddev, crtc, primary, NULL,
Re: [PATCH v2 2/4] drm/panel: Add driver for DJN HX83112A LCD panel
On Fri Jan 12, 2024 at 11:26 AM CET, wrote: > On 12/01/2024 11:23, Linus Walleij wrote: > > On Fri, Jan 12, 2024 at 10:52 AM Luca Weiss > > wrote: > > > >> Since there's zero indication Truly is involved in this panel in my > >> documentation - much less the number 5P65 - I'm not going to add that. > > Ack > > > > > OK then, I fold, thanks for looking into it. > > Keep the Himax hx83112a file name and symbols. > > > >> So in short this panel is the model 9A-3R063-1102B from DJN, which uses > >> a Himax HX83112A driver IC. > > > > So compatible = "djn,9a-3r063-1102b" since the setup sequences for > > hx83112a are clearly for this one display? > > Yep let's settle on that! It's clear to me to use "djn,9a-3r063-1102b" in the driver now but what about dts? Currently here in v2 we have this: compatible = "fairphone,fp4-hx83112a-djn", "himax,hx83112a"; Should this just become this? compatible = "djn,9a-3r063-1102b"; Or e.g. this? compatible = "djn,9a-3r063-1102b", "himax,hx83112a"; Or something else completely? Do we have some documentation / best practises around this maybe? Regards Luca > > Thanks, > Neil > > > > > Yours, > > Linus Walleij
[PATCH v3 0/2] Small runtime PM API changes
Hi folks, Here's a small but a different set of patches for making two relatively minor changes to runtime PM API. I restarted version numbering as this is meaningfully different from the previous set. pm_runtime_get_if_active() loses its second argument as it only made sense to have ign_usage_count argument true. The other change is also small but it has an effect on callers: pm_runtime_put_autosuspend() will, in the future, be re-purposed to include a call to pm_runtime_mark_last_busy() as well. Before this, current users of the function are moved to __pm_runtime_put_autosuspend() (added by this patchset) which will continue to have the current behaviour. I haven't included the conversion patches in this set as I only want to do that once this set has been approved and merged. The tree specific patches can be found here, on linux-next master (there are some V4L2 patches there, too, please ignore them for now): https://git.kernel.org/pub/scm/linux/kernel/git/sailus/linux-next.git/log/?h=pm> Later on, users calling pm_runtime_mark_last_busy() immediately followed by __pm_runtime_put_autosuspend() will be switched back to pm_runtime_put_autosuspend() once its behaviour change has been done (a patch near top of that branch). I'll provide these once the preceding ones have been merged. Comments are welcome. since v2: - Rebase on v6.8-rc1 (no changes). - Add Rodrigo's Reviewed-by: to the 1st patch. since v1: - patch 1: Rename __pm_runtime_get_conditional() as pm_runtime_get_conditional(). - patch 1: Reword documentation on driver use of pm_runtime_get_conditional(). Sakari Ailus (2): pm: runtime: Simplify pm_runtime_get_if_active() usage pm: runtime: Add pm_runtime_put_autosuspend() replacement Documentation/power/runtime_pm.rst | 22 - drivers/accel/ivpu/ivpu_pm.c| 2 +- drivers/base/power/runtime.c| 10 -- drivers/gpu/drm/i915/intel_runtime_pm.c | 2 +- drivers/gpu/drm/xe/xe_pm.c | 2 +- drivers/media/i2c/ccs/ccs-core.c| 2 +- drivers/media/i2c/ov64a40.c | 2 +- drivers/media/i2c/thp7312.c | 2 +- drivers/net/ipa/ipa_smp2p.c | 2 +- drivers/pci/pci.c | 2 +- include/linux/pm_runtime.h | 44 ++--- sound/hda/hdac_device.c | 2 +- 12 files changed, 68 insertions(+), 26 deletions(-) -- 2.39.2
[PATCH v3 1/2] pm: runtime: Simplify pm_runtime_get_if_active() usage
There are two ways to opportunistically increment a device's runtime PM usage count, calling either pm_runtime_get_if_active() or pm_runtime_get_if_in_use(). The former has an argument to tell whether to ignore the usage count or not, and the latter simply calls the former with ign_usage_count set to false. The other users that want to ignore the usage_count will have to explitly set that argument to true which is a bit cumbersome. To make this function more practical to use, remove the ign_usage_count argument from the function. The main implementation is renamed as pm_runtime_get_conditional(). Signed-off-by: Sakari Ailus Reviewed-by: Alex Elder # drivers/net/ipa/ipa_smp2p.c Reviewed-by: Laurent Pinchart Acked-by: Takashi Iwai # sound/ Reviewed-by: Jacek Lawrynowicz # drivers/accel/ivpu/ Acked-by: Rodrigo Vivi # drivers/gpu/drm/i915/ Reviewed-by: Rodrigo Vivi --- Documentation/power/runtime_pm.rst | 5 ++-- drivers/accel/ivpu/ivpu_pm.c| 2 +- drivers/base/power/runtime.c| 10 +--- drivers/gpu/drm/i915/intel_runtime_pm.c | 2 +- drivers/gpu/drm/xe/xe_pm.c | 2 +- drivers/media/i2c/ccs/ccs-core.c| 2 +- drivers/media/i2c/ov64a40.c | 2 +- drivers/media/i2c/thp7312.c | 2 +- drivers/net/ipa/ipa_smp2p.c | 2 +- drivers/pci/pci.c | 2 +- include/linux/pm_runtime.h | 32 + sound/hda/hdac_device.c | 2 +- 12 files changed, 45 insertions(+), 20 deletions(-) diff --git a/Documentation/power/runtime_pm.rst b/Documentation/power/runtime_pm.rst index 65b86e487afe..da99379071a4 100644 --- a/Documentation/power/runtime_pm.rst +++ b/Documentation/power/runtime_pm.rst @@ -396,10 +396,9 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: nonzero, increment the counter and return 1; otherwise return 0 without changing the counter - `int pm_runtime_get_if_active(struct device *dev, bool ign_usage_count);` + `int pm_runtime_get_if_active(struct device *dev);` - return -EINVAL if 'power.disable_depth' is nonzero; otherwise, if the - runtime PM status is RPM_ACTIVE, and either ign_usage_count is true - or the device's usage_count is non-zero, increment the counter and + runtime PM status is RPM_ACTIVE, increment the counter and return 1; otherwise return 0 without changing the counter `void pm_runtime_put_noidle(struct device *dev);` diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index 0af8864cb3b5..c6d93c7a1c58 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -292,7 +292,7 @@ int ivpu_rpm_get_if_active(struct ivpu_device *vdev) { int ret; - ret = pm_runtime_get_if_active(vdev->drm.dev, false); + ret = pm_runtime_get_if_in_use(vdev->drm.dev); drm_WARN_ON(&vdev->drm, ret < 0); return ret; diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 05793c9fbb84..b4cb3f19b0d8 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -1176,7 +1176,7 @@ int __pm_runtime_resume(struct device *dev, int rpmflags) EXPORT_SYMBOL_GPL(__pm_runtime_resume); /** - * pm_runtime_get_if_active - Conditionally bump up device usage counter. + * pm_runtime_get_conditional - Conditionally bump up device usage counter. * @dev: Device to handle. * @ign_usage_count: Whether or not to look at the current usage counter value. * @@ -1196,8 +1196,12 @@ EXPORT_SYMBOL_GPL(__pm_runtime_resume); * * The caller is responsible for decrementing the runtime PM usage counter of * @dev after this function has returned a positive value for it. + * + * This function is not primarily intended for use in drivers, most of which are + * better served by either pm_runtime_get_if_active() or + * pm_runtime_get_if_in_use() instead. */ -int pm_runtime_get_if_active(struct device *dev, bool ign_usage_count) +int pm_runtime_get_conditional(struct device *dev, bool ign_usage_count) { unsigned long flags; int retval; @@ -1218,7 +1222,7 @@ int pm_runtime_get_if_active(struct device *dev, bool ign_usage_count) return retval; } -EXPORT_SYMBOL_GPL(pm_runtime_get_if_active); +EXPORT_SYMBOL_GPL(pm_runtime_get_conditional); /** * __pm_runtime_set_status - Set runtime PM status of a device. diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 860b51b56a92..b5f8abd2a22b 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -246,7 +246,7 @@ static intel_wakeref_t __intel_runtime_pm_get_if_active(struct intel_runtime_pm * function, since the power state is undefined. This applies * atm to the late/early system suspend/resume handlers. */ - if (pm_runtime_get_if_active(rpm->kdev, ignore_usecoun
[PATCH 1/3] accel/ivpu: Fix dev open/close races with unbind
- Add context_list_lock to synchronize user context addition/removal - Use drm_dev_enter() to prevent unbinding the device during ivpu_open() and vpu address allocation Signed-off-by: Jacek Lawrynowicz --- drivers/accel/ivpu/ivpu_drv.c | 110 +- drivers/accel/ivpu/ivpu_drv.h | 3 +- drivers/accel/ivpu/ivpu_gem.c | 18 +++--- drivers/accel/ivpu/ivpu_gem.h | 2 +- drivers/accel/ivpu/ivpu_job.c | 16 ++--- drivers/accel/ivpu/ivpu_job.h | 2 +- 6 files changed, 86 insertions(+), 65 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index 546c0899bb9e..551f4b8fd3a9 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -66,22 +67,20 @@ struct ivpu_file_priv *ivpu_file_priv_get(struct ivpu_file_priv *file_priv) return file_priv; } -struct ivpu_file_priv *ivpu_file_priv_get_by_ctx_id(struct ivpu_device *vdev, unsigned long id) +static void file_priv_unbind(struct ivpu_device *vdev, struct ivpu_file_priv *file_priv) { - struct ivpu_file_priv *file_priv; - - xa_lock_irq(&vdev->context_xa); - file_priv = xa_load(&vdev->context_xa, id); - /* file_priv may still be in context_xa during file_priv_release() */ - if (file_priv && !kref_get_unless_zero(&file_priv->ref)) - file_priv = NULL; - xa_unlock_irq(&vdev->context_xa); - - if (file_priv) - ivpu_dbg(vdev, KREF, "file_priv get by id: ctx %u refcount %u\n", -file_priv->ctx.id, kref_read(&file_priv->ref)); - - return file_priv; + mutex_lock(&file_priv->lock); + if (file_priv->bound) { + ivpu_dbg(vdev, FILE, "file_priv unbind: ctx %u\n", file_priv->ctx.id); + + ivpu_cmdq_release_all_locked(file_priv); + ivpu_jsm_context_release(vdev, file_priv->ctx.id); + ivpu_bo_unbind_all_bos_from_context(vdev, &file_priv->ctx); + ivpu_mmu_user_context_fini(vdev, &file_priv->ctx); + file_priv->bound = false; + drm_WARN_ON(&vdev->drm, !xa_erase_irq(&vdev->context_xa, file_priv->ctx.id)); + } + mutex_unlock(&file_priv->lock); } static void file_priv_release(struct kref *ref) @@ -89,13 +88,15 @@ static void file_priv_release(struct kref *ref) struct ivpu_file_priv *file_priv = container_of(ref, struct ivpu_file_priv, ref); struct ivpu_device *vdev = file_priv->vdev; - ivpu_dbg(vdev, FILE, "file_priv release: ctx %u\n", file_priv->ctx.id); + ivpu_dbg(vdev, FILE, "file_priv release: ctx %u bound %d\n", +file_priv->ctx.id, (bool)file_priv->bound); + + pm_runtime_get_sync(vdev->drm.dev); + mutex_lock(&vdev->context_list_lock); + file_priv_unbind(vdev, file_priv); + mutex_unlock(&vdev->context_list_lock); + pm_runtime_put_autosuspend(vdev->drm.dev); - ivpu_cmdq_release_all(file_priv); - ivpu_jsm_context_release(vdev, file_priv->ctx.id); - ivpu_bo_remove_all_bos_from_context(vdev, &file_priv->ctx); - ivpu_mmu_user_context_fini(vdev, &file_priv->ctx); - drm_WARN_ON(&vdev->drm, xa_erase_irq(&vdev->context_xa, file_priv->ctx.id) != file_priv); mutex_destroy(&file_priv->lock); kfree(file_priv); } @@ -232,49 +233,54 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file) struct ivpu_device *vdev = to_ivpu_device(dev); struct ivpu_file_priv *file_priv; u32 ctx_id; - void *old; - int ret; + int idx, ret; - ret = xa_alloc_irq(&vdev->context_xa, &ctx_id, NULL, vdev->context_xa_limit, GFP_KERNEL); - if (ret) { - ivpu_err(vdev, "Failed to allocate context id: %d\n", ret); - return ret; - } + if (!drm_dev_enter(dev, &idx)) + return -ENODEV; file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL); if (!file_priv) { + ivpu_err(vdev, "Failed to allocate file_priv\n"); ret = -ENOMEM; - goto err_xa_erase; + goto err_dev_exit; } file_priv->vdev = vdev; + file_priv->bound = true; kref_init(&file_priv->ref); mutex_init(&file_priv->lock); + mutex_lock(&vdev->context_list_lock); + + ret = xa_alloc_irq(&vdev->context_xa, &ctx_id, file_priv, + vdev->context_xa_limit, GFP_KERNEL); + if (ret) { + ivpu_err(vdev, "Failed to allocate context id: %d\n", ret); + goto err_unlock; + } + ret = ivpu_mmu_user_context_init(vdev, &file_priv->ctx, ctx_id); if (ret) - goto err_mutex_destroy; + goto err_xa_erase; - old = xa_store_irq(&vdev->context_xa, ctx_id, file_priv, GFP_KERNEL); - if (xa_is_err(old))
[PATCH 0/3] accel/ivpu fixes for 6.8-rc1
Stability fixes for reset, recovery and unbind. Jacek Lawrynowicz (3): accel/ivpu: Fix dev open/close races with unbind accel/ivpu: Improve stability of ivpu_submit_ioctl() accel/ivpu: Improve recovery and reset support drivers/accel/ivpu/ivpu_debugfs.c | 20 +++- drivers/accel/ivpu/ivpu_drv.c | 110 + drivers/accel/ivpu/ivpu_drv.h | 3 +- drivers/accel/ivpu/ivpu_gem.c | 18 ++-- drivers/accel/ivpu/ivpu_gem.h | 2 +- drivers/accel/ivpu/ivpu_hw_37xx.c | 14 +-- drivers/accel/ivpu/ivpu_hw_40xx.c | 8 +- drivers/accel/ivpu/ivpu_ipc.c | 6 +- drivers/accel/ivpu/ivpu_job.c | 157 +- drivers/accel/ivpu/ivpu_job.h | 3 +- drivers/accel/ivpu/ivpu_mmu.c | 14 ++- drivers/accel/ivpu/ivpu_pm.c | 48 ++--- drivers/accel/ivpu/ivpu_pm.h | 6 +- 13 files changed, 218 insertions(+), 191 deletions(-) -- 2.43.0
[PATCH 3/3] accel/ivpu: Improve recovery and reset support
- Synchronize job submission with reset/recovery using reset_lock - Always print recovery reason and call diagnose_failure() - Don't allow for autosupend during recovery - Prevent immediate autosuspend after reset/recovery - Prevent force_recovery for issuing TDR when device is suspended - Reset VPU instead triggering recovery after changing debugfs params Signed-off-by: Jacek Lawrynowicz --- drivers/accel/ivpu/ivpu_debugfs.c | 20 ++--- drivers/accel/ivpu/ivpu_hw_37xx.c | 14 +++-- drivers/accel/ivpu/ivpu_hw_40xx.c | 8 +++--- drivers/accel/ivpu/ivpu_ipc.c | 6 ++-- drivers/accel/ivpu/ivpu_job.c | 2 ++ drivers/accel/ivpu/ivpu_mmu.c | 14 - drivers/accel/ivpu/ivpu_pm.c | 48 --- drivers/accel/ivpu/ivpu_pm.h | 6 ++-- 8 files changed, 70 insertions(+), 48 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c index 19035230563d..7cb962e21453 100644 --- a/drivers/accel/ivpu/ivpu_debugfs.c +++ b/drivers/accel/ivpu/ivpu_debugfs.c @@ -102,7 +102,7 @@ static int reset_pending_show(struct seq_file *s, void *v) { struct ivpu_device *vdev = seq_to_ivpu(s); - seq_printf(s, "%d\n", atomic_read(&vdev->pm->in_reset)); + seq_printf(s, "%d\n", atomic_read(&vdev->pm->reset_pending)); return 0; } @@ -130,7 +130,9 @@ dvfs_mode_fops_write(struct file *file, const char __user *user_buf, size_t size fw->dvfs_mode = dvfs_mode; - ivpu_pm_schedule_recovery(vdev); + ret = pci_try_reset_function(to_pci_dev(vdev->drm.dev)); + if (ret) + return ret; return size; } @@ -190,7 +192,10 @@ fw_profiling_freq_fops_write(struct file *file, const char __user *user_buf, return ret; ivpu_hw_profiling_freq_drive(vdev, enable); - ivpu_pm_schedule_recovery(vdev); + + ret = pci_try_reset_function(to_pci_dev(vdev->drm.dev)); + if (ret) + return ret; return size; } @@ -301,11 +306,18 @@ static ssize_t ivpu_force_recovery_fn(struct file *file, const char __user *user_buf, size_t size, loff_t *pos) { struct ivpu_device *vdev = file->private_data; + int ret; if (!size) return -EINVAL; - ivpu_pm_schedule_recovery(vdev); + ret = ivpu_rpm_get(vdev); + if (ret) + return ret; + + ivpu_pm_trigger_recovery(vdev, "debugfs"); + flush_work(&vdev->pm->recovery_work); + ivpu_rpm_put(vdev); return size; } diff --git a/drivers/accel/ivpu/ivpu_hw_37xx.c b/drivers/accel/ivpu/ivpu_hw_37xx.c index 574cdeefb66b..f15a93d83057 100644 --- a/drivers/accel/ivpu/ivpu_hw_37xx.c +++ b/drivers/accel/ivpu/ivpu_hw_37xx.c @@ -875,24 +875,18 @@ static void ivpu_hw_37xx_irq_disable(struct ivpu_device *vdev) static void ivpu_hw_37xx_irq_wdt_nce_handler(struct ivpu_device *vdev) { - ivpu_err_ratelimited(vdev, "WDT NCE irq\n"); - - ivpu_pm_schedule_recovery(vdev); + ivpu_pm_trigger_recovery(vdev, "WDT NCE IRQ"); } static void ivpu_hw_37xx_irq_wdt_mss_handler(struct ivpu_device *vdev) { - ivpu_err_ratelimited(vdev, "WDT MSS irq\n"); - ivpu_hw_wdt_disable(vdev); - ivpu_pm_schedule_recovery(vdev); + ivpu_pm_trigger_recovery(vdev, "WDT MSS IRQ"); } static void ivpu_hw_37xx_irq_noc_firewall_handler(struct ivpu_device *vdev) { - ivpu_err_ratelimited(vdev, "NOC Firewall irq\n"); - - ivpu_pm_schedule_recovery(vdev); + ivpu_pm_trigger_recovery(vdev, "NOC Firewall IRQ"); } /* Handler for IRQs from VPU core (irqV) */ @@ -970,7 +964,7 @@ static bool ivpu_hw_37xx_irqb_handler(struct ivpu_device *vdev, int irq) REGB_WR32(VPU_37XX_BUTTRESS_INTERRUPT_STAT, status); if (schedule_recovery) - ivpu_pm_schedule_recovery(vdev); + ivpu_pm_trigger_recovery(vdev, "Buttress IRQ"); return true; } diff --git a/drivers/accel/ivpu/ivpu_hw_40xx.c b/drivers/accel/ivpu/ivpu_hw_40xx.c index eba2fdef2ace..af7081cadaae 100644 --- a/drivers/accel/ivpu/ivpu_hw_40xx.c +++ b/drivers/accel/ivpu/ivpu_hw_40xx.c @@ -1032,18 +1032,18 @@ static void ivpu_hw_40xx_irq_disable(struct ivpu_device *vdev) static void ivpu_hw_40xx_irq_wdt_nce_handler(struct ivpu_device *vdev) { /* TODO: For LNN hang consider engine reset instead of full recovery */ - ivpu_pm_schedule_recovery(vdev); + ivpu_pm_trigger_recovery(vdev, "WDT NCE IRQ"); } static void ivpu_hw_40xx_irq_wdt_mss_handler(struct ivpu_device *vdev) { ivpu_hw_wdt_disable(vdev); - ivpu_pm_schedule_recovery(vdev); + ivpu_pm_trigger_recovery(vdev, "WDT MSS IRQ"); } static void ivpu_hw_40xx_irq_noc_firewall_handler(struct ivpu_device *vdev) { - ivpu_pm_schedule_recovery(vdev); + ivpu_pm_trigger_recovery(vdev, "NOC Firewall IRQ"); } /* Handler for IRQs from VPU core (irqV) */ @@ -1137,7
[PATCH 2/3] accel/ivpu: Improve stability of ivpu_submit_ioctl()
- Wake up the device as late as possible - Remove job reference counting in order to simplify the code - Don't put jobs that are not fully submitted on submitted_jobs_xa in order to avoid potential races with reset/recovery Signed-off-by: Jacek Lawrynowicz --- drivers/accel/ivpu/ivpu_job.c | 139 +++--- drivers/accel/ivpu/ivpu_job.h | 1 - 2 files changed, 62 insertions(+), 78 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 4fed0c05e051..d9b47a04b35f 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -125,7 +125,7 @@ void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv) /* * Mark the doorbell as unregistered and reset job queue pointers. * This function needs to be called when the VPU hardware is restarted - * and FW looses job queue state. The next time job queue is used it + * and FW loses job queue state. The next time job queue is used it * will be registered again. */ static void ivpu_cmdq_reset_locked(struct ivpu_file_priv *file_priv, u16 engine) @@ -239,60 +239,32 @@ static struct dma_fence *ivpu_fence_create(struct ivpu_device *vdev) return &fence->base; } -static void job_get(struct ivpu_job *job, struct ivpu_job **link) +static void ivpu_job_destroy(struct ivpu_job *job) { struct ivpu_device *vdev = job->vdev; - - kref_get(&job->ref); - *link = job; - - ivpu_dbg(vdev, KREF, "Job get: id %u refcount %u\n", job->job_id, kref_read(&job->ref)); -} - -static void job_release(struct kref *ref) -{ - struct ivpu_job *job = container_of(ref, struct ivpu_job, ref); - struct ivpu_device *vdev = job->vdev; u32 i; + ivpu_dbg(vdev, JOB, "Job destroyed: id %3u ctx %2d engine %d", +job->job_id, job->file_priv->ctx.id, job->engine_idx); + for (i = 0; i < job->bo_count; i++) if (job->bos[i]) drm_gem_object_put(&job->bos[i]->base.base); dma_fence_put(job->done_fence); ivpu_file_priv_put(&job->file_priv); - - ivpu_dbg(vdev, KREF, "Job released: id %u\n", job->job_id); kfree(job); - - /* Allow the VPU to get suspended, must be called after ivpu_file_priv_put() */ - ivpu_rpm_put(vdev); -} - -static void job_put(struct ivpu_job *job) -{ - struct ivpu_device *vdev = job->vdev; - - ivpu_dbg(vdev, KREF, "Job put: id %u refcount %u\n", job->job_id, kref_read(&job->ref)); - kref_put(&job->ref, job_release); } static struct ivpu_job * -ivpu_create_job(struct ivpu_file_priv *file_priv, u32 engine_idx, u32 bo_count) +ivpu_job_create(struct ivpu_file_priv *file_priv, u32 engine_idx, u32 bo_count) { struct ivpu_device *vdev = file_priv->vdev; struct ivpu_job *job; - int ret; - - ret = ivpu_rpm_get(vdev); - if (ret < 0) - return NULL; job = kzalloc(struct_size(job, bos, bo_count), GFP_KERNEL); if (!job) - goto err_rpm_put; - - kref_init(&job->ref); + return NULL; job->vdev = vdev; job->engine_idx = engine_idx; @@ -306,17 +278,14 @@ ivpu_create_job(struct ivpu_file_priv *file_priv, u32 engine_idx, u32 bo_count) job->file_priv = ivpu_file_priv_get(file_priv); ivpu_dbg(vdev, JOB, "Job created: ctx %2d engine %d", file_priv->ctx.id, job->engine_idx); - return job; err_free_job: kfree(job); -err_rpm_put: - ivpu_rpm_put(vdev); return NULL; } -static int ivpu_job_done(struct ivpu_device *vdev, u32 job_id, u32 job_status) +static int ivpu_job_signal_and_destroy(struct ivpu_device *vdev, u32 job_id, u32 job_status) { struct ivpu_job *job; @@ -333,9 +302,10 @@ static int ivpu_job_done(struct ivpu_device *vdev, u32 job_id, u32 job_status) ivpu_dbg(vdev, JOB, "Job complete: id %3u ctx %2d engine %d status 0x%x\n", job->job_id, job->file_priv->ctx.id, job->engine_idx, job_status); + ivpu_job_destroy(job); ivpu_stop_job_timeout_detection(vdev); - job_put(job); + ivpu_rpm_put(vdev); return 0; } @@ -345,10 +315,10 @@ void ivpu_jobs_abort_all(struct ivpu_device *vdev) unsigned long id; xa_for_each(&vdev->submitted_jobs_xa, id, job) - ivpu_job_done(vdev, id, VPU_JSM_STATUS_ABORTED); + ivpu_job_signal_and_destroy(vdev, id, VPU_JSM_STATUS_ABORTED); } -static int ivpu_direct_job_submission(struct ivpu_job *job) +static int ivpu_job_submit(struct ivpu_job *job) { struct ivpu_file_priv *file_priv = job->file_priv; struct ivpu_device *vdev = job->vdev; @@ -356,53 +326,65 @@ static int ivpu_direct_job_submission(struct ivpu_job *job) struct ivpu_cmdq *cmdq; int ret; + ret = ivpu_rpm_get(vdev); + if (ret < 0) + return ret; + mutex_lock(&file_priv->lock);
Re: [PATCH v2] accel/ivpu: Disable PLL after VPU IP reset during FLR
Applied to drm-misc-fixes On 24.10.2023 18:53, Stanislaw Gruszka wrote: > From: Jacek Lawrynowicz > > IP reset has to followed by ivpu_pll_disable() to properly enter > reset state. > > Fixes: 828d63042aec ("accel/ivpu: Don't enter d0i3 during FLR") > Cc: sta...@vger.kernel.org > Signed-off-by: Jacek Lawrynowicz > Reviewed-by: Stanislaw Gruszka > Signed-off-by: Stanislaw Gruszka > --- > v2: use ivpu_hw_37xx_ip_reset() in ivpu_hw_37xx_power_up() > > drivers/accel/ivpu/ivpu_hw_37xx.c | 23 --- > drivers/accel/ivpu/ivpu_hw_40xx.c | 23 --- > 2 files changed, 40 insertions(+), 6 deletions(-) > > diff --git a/drivers/accel/ivpu/ivpu_hw_37xx.c > b/drivers/accel/ivpu/ivpu_hw_37xx.c > index 5c0246b9e522..56b53833ede2 100644 > --- a/drivers/accel/ivpu/ivpu_hw_37xx.c > +++ b/drivers/accel/ivpu/ivpu_hw_37xx.c > @@ -598,7 +598,7 @@ static int ivpu_hw_37xx_info_init(struct ivpu_device > *vdev) > return 0; > } > > -static int ivpu_hw_37xx_reset(struct ivpu_device *vdev) > +static int ivpu_hw_37xx_ip_reset(struct ivpu_device *vdev) > { > int ret; > u32 val; > @@ -623,6 +623,23 @@ static int ivpu_hw_37xx_reset(struct ivpu_device *vdev) > return ret; > } > > +static int ivpu_hw_37xx_reset(struct ivpu_device *vdev) > +{ > + int ret = 0; > + > + if (ivpu_hw_37xx_ip_reset(vdev)) { > + ivpu_err(vdev, "Failed to reset VPU IP\n"); > + ret = -EIO; > + } > + > + if (ivpu_pll_disable(vdev)) { > + ivpu_err(vdev, "Failed to disable PLL\n"); > + ret = -EIO; > + } > + > + return ret; > +} > + > static int ivpu_hw_37xx_d0i3_enable(struct ivpu_device *vdev) > { > int ret; > @@ -651,7 +668,7 @@ static int ivpu_hw_37xx_power_up(struct ivpu_device *vdev) > { > int ret; > > - ret = ivpu_hw_37xx_reset(vdev); > + ret = ivpu_hw_37xx_ip_reset(vdev); > if (ret) > ivpu_warn(vdev, "Failed to reset HW: %d\n", ret); > > @@ -722,7 +739,7 @@ static int ivpu_hw_37xx_power_down(struct ivpu_device > *vdev) > { > int ret = 0; > > - if (!ivpu_hw_37xx_is_idle(vdev) && ivpu_hw_37xx_reset(vdev)) > + if (!ivpu_hw_37xx_is_idle(vdev) && ivpu_hw_37xx_ip_reset(vdev)) > ivpu_err(vdev, "Failed to reset the VPU\n"); > > if (ivpu_pll_disable(vdev)) { > diff --git a/drivers/accel/ivpu/ivpu_hw_40xx.c > b/drivers/accel/ivpu/ivpu_hw_40xx.c > index e691c49c9841..b25d02dc541b 100644 > --- a/drivers/accel/ivpu/ivpu_hw_40xx.c > +++ b/drivers/accel/ivpu/ivpu_hw_40xx.c > @@ -742,7 +742,7 @@ static int ivpu_hw_40xx_info_init(struct ivpu_device > *vdev) > return 0; > } > > -static int ivpu_hw_40xx_reset(struct ivpu_device *vdev) > +static int ivpu_hw_40xx_ip_reset(struct ivpu_device *vdev) > { > int ret; > u32 val; > @@ -764,6 +764,23 @@ static int ivpu_hw_40xx_reset(struct ivpu_device *vdev) > return ret; > } > > +static int ivpu_hw_40xx_reset(struct ivpu_device *vdev) > +{ > + int ret = 0; > + > + if (ivpu_hw_40xx_ip_reset(vdev)) { > + ivpu_err(vdev, "Failed to reset VPU IP\n"); > + ret = -EIO; > + } > + > + if (ivpu_pll_disable(vdev)) { > + ivpu_err(vdev, "Failed to disable PLL\n"); > + ret = -EIO; > + } > + > + return ret; > +} > + > static int ivpu_hw_40xx_d0i3_enable(struct ivpu_device *vdev) > { > int ret; > @@ -824,7 +841,7 @@ static int ivpu_hw_40xx_power_up(struct ivpu_device *vdev) > { > int ret; > > - ret = ivpu_hw_40xx_reset(vdev); > + ret = ivpu_hw_40xx_ip_reset(vdev); > if (ret) { > ivpu_err(vdev, "Failed to reset HW: %d\n", ret); > return ret; > @@ -902,7 +919,7 @@ static int ivpu_hw_40xx_power_down(struct ivpu_device > *vdev) > { > int ret = 0; > > - if (!ivpu_hw_40xx_is_idle(vdev) && ivpu_hw_40xx_reset(vdev)) > + if (!ivpu_hw_40xx_is_idle(vdev) && ivpu_hw_40xx_ip_reset(vdev)) > ivpu_warn(vdev, "Failed to reset the VPU\n"); > > if (ivpu_pll_disable(vdev)) {
Re: [Linaro-mm-sig] [PATCH v5 1/6] dma-buf: Add dma_buf_{begin,end}_access()
Am 22.01.24 um 12:01 schrieb Paul Cercueil: Hi Christian, Le lundi 22 janvier 2024 à 11:35 +0100, Christian König a écrit : Am 19.01.24 um 15:13 schrieb Paul Cercueil: These functions should be used by device drivers when they start and stop accessing the data of DMABUF. It allows DMABUF importers to cache the dma_buf_attachment while ensuring that the data they want to access is available for their device when the DMA transfers take place. As Daniel already noted as well this is a complete no-go from the DMA-buf design point of view. What do you mean "as Daniel already noted"? It was him who suggested this. Sorry, I haven't fully catched up to the discussion then. In general DMA-buf is build around the idea that the data can be accessed coherently by the involved devices. Having a begin/end of access for devices was brought up multiple times but so far rejected for good reasons. That an exporter has to call extra functions to access his own buffers is a complete no-go for the design since this forces exporters into doing extra steps for allowing importers to access their data. That in turn is pretty much un-testable unless you have every possible importer around while testing the exporter. Regards, Christian. Regards, Christian. Cheers, -Paul Signed-off-by: Paul Cercueil --- v5: New patch --- drivers/dma-buf/dma-buf.c | 66 +++ include/linux/dma-buf.h | 37 ++ 2 files changed, 103 insertions(+) diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 8fe5aa67b167..a8bab6c18fcd 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -830,6 +830,8 @@ static struct sg_table * __map_dma_buf(struct dma_buf_attachment *attach, * - dma_buf_mmap() * - dma_buf_begin_cpu_access() * - dma_buf_end_cpu_access() + * - dma_buf_begin_access() + * - dma_buf_end_access() * - dma_buf_map_attachment_unlocked() * - dma_buf_unmap_attachment_unlocked() * - dma_buf_vmap_unlocked() @@ -1602,6 +1604,70 @@ void dma_buf_vunmap_unlocked(struct dma_buf *dmabuf, struct iosys_map *map) } EXPORT_SYMBOL_NS_GPL(dma_buf_vunmap_unlocked, DMA_BUF); +/** + * @dma_buf_begin_access - Call before any hardware access from/to the DMABUF + * @attach:[in]attachment used for hardware access + * @sg_table: [in]scatterlist used for the DMA transfer + * @direction: [in] direction of DMA transfer + */ +int dma_buf_begin_access(struct dma_buf_attachment *attach, +struct sg_table *sgt, enum dma_data_direction dir) +{ + struct dma_buf *dmabuf; + bool cookie; + int ret; + + if (WARN_ON(!attach)) + return -EINVAL; + + dmabuf = attach->dmabuf; + + if (!dmabuf->ops->begin_access) + return 0; + + cookie = dma_fence_begin_signalling(); + ret = dmabuf->ops->begin_access(attach, sgt, dir); + dma_fence_end_signalling(cookie); + + if (WARN_ON_ONCE(ret)) + return ret; + + return 0; +} +EXPORT_SYMBOL_NS_GPL(dma_buf_begin_access, DMA_BUF); + +/** + * @dma_buf_end_access - Call after any hardware access from/to the DMABUF + * @attach:[in]attachment used for hardware access + * @sg_table: [in]scatterlist used for the DMA transfer + * @direction: [in] direction of DMA transfer + */ +int dma_buf_end_access(struct dma_buf_attachment *attach, + struct sg_table *sgt, enum dma_data_direction dir) +{ + struct dma_buf *dmabuf; + bool cookie; + int ret; + + if (WARN_ON(!attach)) + return -EINVAL; + + dmabuf = attach->dmabuf; + + if (!dmabuf->ops->end_access) + return 0; + + cookie = dma_fence_begin_signalling(); + ret = dmabuf->ops->end_access(attach, sgt, dir); + dma_fence_end_signalling(cookie); + + if (WARN_ON_ONCE(ret)) + return ret; + + return 0; +} +EXPORT_SYMBOL_NS_GPL(dma_buf_end_access, DMA_BUF); + #ifdef CONFIG_DEBUG_FS static int dma_buf_debug_show(struct seq_file *s, void *unused) { diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index 8ff4add71f88..8ba612c7cc16 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -246,6 +246,38 @@ struct dma_buf_ops { */ int (*end_cpu_access)(struct dma_buf *, enum dma_data_direction); + /** +* @begin_access: +* +* This is called from dma_buf_begin_access() when a device driver +* wants to access the data of the DMABUF. The exporter can use this +* to flush/sync the caches if needed. +* +* This callback is optional. +* +* Returns: +* +* 0 on success or a negative error code on failure. +*/ + int (*begin_access)(struct dma_buf_attachment *, struct sg_table *, + enu
[PATCH v4 1/3] drm/i915/vma: Fix UAF on destroy against retire race
Object debugging tools were sporadically reporting illegal attempts to free a still active i915 VMA object when parking a GPU tile believed to be idle. [161.359441] ODEBUG: free active (active state 0) object: 88811643b958 object type: i915_active hint: __i915_vma_active+0x0/0x50 [i915] [161.360082] WARNING: CPU: 5 PID: 276 at lib/debugobjects.c:514 debug_print_object+0x80/0xb0 ... [161.360304] CPU: 5 PID: 276 Comm: kworker/5:2 Not tainted 6.5.0-rc1-CI_DRM_13375-g003f860e5577+ #1 [161.360314] Hardware name: Intel Corporation Rocket Lake Client Platform/RocketLake S UDIMM 6L RVP, BIOS RKLSFWI1.R00.3173.A03.2204210138 04/21/2022 [161.360322] Workqueue: i915-unordered __intel_wakeref_put_work [i915] [161.360592] RIP: 0010:debug_print_object+0x80/0xb0 ... [161.361347] debug_object_free+0xeb/0x110 [161.361362] i915_active_fini+0x14/0x130 [i915] [161.361866] release_references+0xfe/0x1f0 [i915] [161.362543] i915_vma_parked+0x1db/0x380 [i915] [161.363129] __gt_park+0x121/0x230 [i915] [161.363515] intel_wakeref_put_last+0x1f/0x70 [i915] That has been tracked down to be happening when another thread is deactivating the VMA inside __active_retire() helper, after the VMA's active counter has been already decremented to 0, but before deactivation of the VMA's object is reported to the object debugging tool. We could prevent from that race by serializing i915_active_fini() with __active_retire() via ref->tree_lock, but that wouldn't stop the VMA from being used, e.g. from __i915_vma_retire() called at the end of __active_retire(), after that VMA has been already freed by a concurrent i915_vma_destroy() on return from the i915_active_fini(). Then, we should rather fix the issue at the VMA level, not in i915_active. Since __i915_vma_parked() is called from __gt_park() on last put of the GT's wakeref, the issue could be addressed by holding the GT wakeref long enough for __active_retire() to complete before that wakeref is released and the GT parked. A VMA associated with a request doesn't acquire a GT wakeref by itself. Instead, it depends on a wakeref held directly by the request's active intel_context for a GT associated with its VM, and indirectly on that intel_context's engine wakeref if the engine belongs to the same GT as the VMA's VM. In case of single-tile platforms, at least one of those wakerefs is usually held long enough for the request's VMA to be deactivated on time, before it is destroyed on last put of its VM GT wakeref. However, on multi-tile platforms, a request may use a VMA from a tile other than the one that hosts the request's engine, then it is protected only with the intel_context's VM GT wakeref. There was an attempt to fix this issue on 2-tile Meteor Lake by acquiring an extra wakeref for a Primary GT from i915_gem_do_execbuffer() -- see commit f56fe3e91787 ("drm/i915: Fix a VMA UAF for multi-gt platform"). However, it occurred insufficient -- the issue was still reported by CI. That wakeref was released on exit from i915_gem_do_execbuffer(), then potentially before completion of the request and deactivation of its associated VMAs. OTOH, CI reports indicate that single-tile platforms also suffer sporadically from the same race. I believe the issue was introduced by commit d93939730347 ("drm/i915: Remove the vma refcount") which moved a call to i915_active_fini() from a dropped i915_vma_release(), called on last put of the removed VMA kref, to i915_vma_parked() processing path called on last put of a GT wakeref. However, its visibility to the object debugging tool was suppressed by a bug in i915_active that was fixed two weeks later with commit e92eb246feb9 ("drm/i915/active: Fix missing debug object activation"). Fix the issue by getting a wakeref for the VMA's tile when activating it, and putting that wakeref only after the VMA is deactivated. However, exclude global GTT from that processing path, otherwise the GPU never goes idle. Since __i915_vma_retire() may be called from atomic contexts, use async variant of wakeref put. v4: Refresh on top of commit 5e4e06e4087e ("drm/i915: Track gt pm wakerefs") (Andi), - for more easy backporting, split out removal of former insufficient workarounds and move them to separate patches (Nirmoy). - clean up commit message and description a bit. v3: Identify root cause more precisely, and a commit to blame, - identify and drop former workarounds, - update commit message and description. v2: Get the wakeref before VM mutex to avoid circular locking dependency, - drop questionable Fixes: tag. Fixes: d93939730347 ("drm/i915: Remove the vma refcount") Closes: https://gitlab.freedesktop.org/drm/intel/issues/8875 Signed-off-by: Janusz Krzysztofik Cc: Thomas Hellström Cc: Nirmoy Das Cc: Andi Shyti Cc: sta...@vger.kernel.org # v5.19+ --- drivers/gpu/drm/i915/i915_vma.c | 26 +++--- drivers/gpu/drm/i915/i915_vma_types.h | 1 + 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/
[PATCH v4 2/3] Manually revert "drm/i915: Fix a VMA UAF for multi-gt platform"
This reverts changes introduced by commit f56fe3e91787, obsoleted by "drm/i915/vma: Fix UAF on destroy against retire race". Signed-off-by: Janusz Krzysztofik --- drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 17 - 1 file changed, 17 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index d3a771afb083e..cedca8fd8754d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -2686,7 +2686,6 @@ static int eb_select_engine(struct i915_execbuffer *eb) { struct intel_context *ce, *child; - struct intel_gt *gt; unsigned int idx; int err; @@ -2710,17 +2709,10 @@ eb_select_engine(struct i915_execbuffer *eb) } } eb->num_batches = ce->parallel.number_children + 1; - gt = ce->engine->gt; for_each_child(ce, child) intel_context_get(child); eb->wakeref = intel_gt_pm_get(ce->engine->gt); - /* -* Keep GT0 active on MTL so that i915_vma_parked() doesn't -* free VMAs while execbuf ioctl is validating VMAs. -*/ - if (gt->info.id) - eb->wakeref_gt0 = intel_gt_pm_get(to_gt(gt->i915)); if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) { err = intel_context_alloc_state(ce); @@ -2759,9 +2751,6 @@ eb_select_engine(struct i915_execbuffer *eb) return err; err: - if (gt->info.id) - intel_gt_pm_put(to_gt(gt->i915), eb->wakeref_gt0); - intel_gt_pm_put(ce->engine->gt, eb->wakeref); for_each_child(ce, child) intel_context_put(child); @@ -2775,12 +2764,6 @@ eb_put_engine(struct i915_execbuffer *eb) struct intel_context *child; i915_vm_put(eb->context->vm); - /* -* This works in conjunction with eb_select_engine() to prevent -* i915_vma_parked() from interfering while execbuf validates vmas. -*/ - if (eb->gt->info.id) - intel_gt_pm_put(to_gt(eb->gt->i915), eb->wakeref_gt0); intel_gt_pm_put(eb->context->engine->gt, eb->wakeref); for_each_child(eb->context, child) intel_context_put(child); -- 2.43.0
[PATCH v4 3/3] Revert "drm/i915: Wait for active retire before i915_active_fini()"
This reverts commit 7a2280e8dcd2f1f436db9631287c0b21cf6a92b0, obsoleted by "drm/i915/vma: Fix UAF on destroy against retire race". Signed-off-by: Janusz Krzysztofik --- drivers/gpu/drm/i915/i915_vma.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 604d420b9e1fd..09b8a6b52d065 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -1752,8 +1752,6 @@ static void release_references(struct i915_vma *vma, struct intel_gt *gt, if (vm_ddestroy) i915_vm_resv_put(vma->vm); - /* Wait for async active retire */ - i915_active_wait(&vma->active); i915_active_fini(&vma->active); GEM_WARN_ON(vma->resource); i915_vma_free(vma); -- 2.43.0
[PATCH AUTOSEL 6.7 04/88] drm: Fix color LUT rounding
From: Ville Syrjälä [ Upstream commit c6fbb6bca10838485b820e8a26c23996f77ce580 ] The current implementation of drm_color_lut_extract() generates weird results. Eg. if we go through all the values for 16->8bpc conversion we see the following pattern: inout (count) 0 - 7f -> 0 (128) 80 - 17f -> 1 (256) 180 - 27f -> 2 (256) 280 - 37f -> 3 (256) ... fb80 - fc7f -> fc (256) fc80 - fd7f -> fd (256) fd80 - fe7f -> fe (256) fe80 - -> ff (384) So less values map to 0 and more values map 0xff, which doesn't seem particularly great. To get just the same number of input values to map to the same output values we'd just need to drop the rounding entrirely. But perhaps a better idea would be to follow the OpenGL int<->float conversion rules, in which case we get the following results: inout (count) 0 - 80 -> 0 (129) 81 - 181 -> 1 (257) 182 - 282 -> 2 (257) 283 - 383 -> 3 (257) ... fc7c - fd7c -> fc (257) fd7d - fe7d -> fd (257) fe7e - ff7e -> fe (257) ff7f - -> ff (129) Note that since the divisor is constant the compiler is able to optimize away the integer division in most cases. The only exception is the _ULL() case on 32bit architectures since that gets emitted as inline asm via do_div() and thus the compiler doesn't get to optimize it. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20231013131402.24072-2-ville.syrj...@linux.intel.com Reviewed-by: Chaitanya Kumar Borah Reviewed-by: Jani Nikula Acked-by: Maxime Ripard Signed-off-by: Sasha Levin --- include/drm/drm_color_mgmt.h | 19 --- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index 81c298488b0c..54b2b2467bfd 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -36,20 +36,17 @@ struct drm_plane; * * Extract a degamma/gamma LUT value provided by user (in the form of * &drm_color_lut entries) and round it to the precision supported by the - * hardware. + * hardware, following OpenGL int<->float conversion rules + * (see eg. OpenGL 4.6 specification - 2.3.5 Fixed-Point Data Conversions). */ static inline u32 drm_color_lut_extract(u32 user_input, int bit_precision) { - u32 val = user_input; - u32 max = 0x >> (16 - bit_precision); - - /* Round only if we're not using full precision. */ - if (bit_precision < 16) { - val += 1UL << (16 - bit_precision - 1); - val >>= 16 - bit_precision; - } - - return clamp_val(val, 0, max); + if (bit_precision > 16) + return DIV_ROUND_CLOSEST_ULL(mul_u32_u32(user_input, (1 << bit_precision) - 1), +(1 << 16) - 1); + else + return DIV_ROUND_CLOSEST(user_input * ((1 << bit_precision) - 1), +(1 << 16) - 1); } u64 drm_color_ctm_s31_32_to_qm_n(u64 user_input, u32 m, u32 n); -- 2.43.0
[PATCH AUTOSEL 6.7 08/88] drm/msm/a690: Fix reg values for a690
From: Danylo Piliaiev [ Upstream commit 07e6de738aa6f0e873463e9ca88bdb7081c4bfd4 ] KGSL doesn't support a690 so all reg values were the same as on a660. Now we know the values and they are different from the windows driver. This fixes hangs on D3D12 games and some CTS tests. Signed-off-by: Danylo Piliaiev Signed-off-by: Rob Clark Patchwork: https://patchwork.freedesktop.org/patch/568931/ Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 23 +-- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 7a0220d29a23..500ed2d183fc 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1312,6 +1312,7 @@ static void a6xx_set_ubwc_config(struct msm_gpu *gpu) if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu) || + adreno_is_a690(adreno_gpu) || adreno_is_a730(adreno_gpu) || adreno_is_a740_family(adreno_gpu)) { /* TODO: get ddr type from bootloader and use 2 for LPDDR4 */ @@ -1321,13 +1322,6 @@ static void a6xx_set_ubwc_config(struct msm_gpu *gpu) uavflagprd_inv = 2; } - if (adreno_is_a690(adreno_gpu)) { - hbb_lo = 2; - amsbc = 1; - rgb565_predicator = 1; - uavflagprd_inv = 2; - } - if (adreno_is_7c3(adreno_gpu)) { hbb_lo = 1; amsbc = 1; @@ -1741,7 +1735,9 @@ static int hw_init(struct msm_gpu *gpu) /* Setting the primFifo thresholds default values, * and vccCacheSkipDis=1 bit (0x200) for A640 and newer */ - if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu) || adreno_is_a690(adreno_gpu)) + if (adreno_is_a690(adreno_gpu)) + gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00800200); + else if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu)) gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00300200); else if (adreno_is_a640_family(adreno_gpu) || adreno_is_7c3(adreno_gpu)) gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00200200); @@ -1775,6 +1771,8 @@ static int hw_init(struct msm_gpu *gpu) if (adreno_is_a730(adreno_gpu) || adreno_is_a740_family(adreno_gpu)) gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0xcf); + else if (adreno_is_a690(adreno_gpu)) + gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x4f); else if (adreno_is_a619(adreno_gpu)) gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x3f); else if (adreno_is_a610(adreno_gpu)) @@ -1808,12 +1806,17 @@ static int hw_init(struct msm_gpu *gpu) a6xx_set_cp_protect(gpu); if (adreno_is_a660_family(adreno_gpu)) { - gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, 0x1); + if (adreno_is_a690(adreno_gpu)) + gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, 0x00028801); + else + gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, 0x1); gpu_write(gpu, REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL, 0x0); } + if (adreno_is_a690(adreno_gpu)) + gpu_write(gpu, REG_A6XX_UCHE_CMDQ_CONFIG, 0x90); /* Set dualQ + disable afull for A660 GPU */ - if (adreno_is_a660(adreno_gpu)) + else if (adreno_is_a660(adreno_gpu)) gpu_write(gpu, REG_A6XX_UCHE_CMDQ_CONFIG, 0x66906); else if (adreno_is_a7xx(adreno_gpu)) gpu_write(gpu, REG_A6XX_UCHE_CMDQ_CONFIG, -- 2.43.0
[PATCH AUTOSEL 6.7 12/88] drm/bridge: anx7625: Fix Set HPD irq detect window to 2ms
From: Xin Ji [ Upstream commit e3af7053de3f685c96158373bc234b2feca1f160 ] Polling firmware HPD GPIO status, set HPD irq detect window to 2ms after firmware HPD GPIO initial done Signed-off-by: Xin Ji Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20231120091038.284825-2-...@analogixsemi.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/bridge/analogix/anx7625.c | 51 --- drivers/gpu/drm/bridge/analogix/anx7625.h | 4 ++ 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 8f740154707d..7afb7edc8ae3 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1298,10 +1298,32 @@ static void anx7625_config(struct anx7625_data *ctx) XTAL_FRQ_SEL, XTAL_FRQ_27M); } +static int anx7625_hpd_timer_config(struct anx7625_data *ctx) +{ + int ret; + + /* Set irq detect window to 2ms */ + ret = anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, + HPD_DET_TIMER_BIT0_7, HPD_TIME & 0xFF); + ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, +HPD_DET_TIMER_BIT8_15, +(HPD_TIME >> 8) & 0xFF); + ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, +HPD_DET_TIMER_BIT16_23, +(HPD_TIME >> 16) & 0xFF); + + return ret; +} + +static int anx7625_read_hpd_gpio_config_status(struct anx7625_data *ctx) +{ + return anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, GPIO_CTRL_2); +} + static void anx7625_disable_pd_protocol(struct anx7625_data *ctx) { struct device *dev = ctx->dev; - int ret; + int ret, val; /* Reset main ocm */ ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client, 0x88, 0x40); @@ -1315,6 +1337,19 @@ static void anx7625_disable_pd_protocol(struct anx7625_data *ctx) DRM_DEV_DEBUG_DRIVER(dev, "disable PD feature fail.\n"); else DRM_DEV_DEBUG_DRIVER(dev, "disable PD feature succeeded.\n"); + + /* +* Make sure the HPD GPIO already be configured after OCM release before +* setting HPD detect window register. Here we poll the status register +* at maximum 40ms, then config HPD irq detect window register +*/ + readx_poll_timeout(anx7625_read_hpd_gpio_config_status, + ctx, val, + ((val & HPD_SOURCE) || (val < 0)), + 2000, 2000 * 20); + + /* Set HPD irq detect window to 2ms */ + anx7625_hpd_timer_config(ctx); } static int anx7625_ocm_loading_check(struct anx7625_data *ctx) @@ -1437,20 +1472,6 @@ static void anx7625_start_dp_work(struct anx7625_data *ctx) static int anx7625_read_hpd_status_p0(struct anx7625_data *ctx) { - int ret; - - /* Set irq detect window to 2ms */ - ret = anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, - HPD_DET_TIMER_BIT0_7, HPD_TIME & 0xFF); - ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, -HPD_DET_TIMER_BIT8_15, -(HPD_TIME >> 8) & 0xFF); - ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, -HPD_DET_TIMER_BIT16_23, -(HPD_TIME >> 16) & 0xFF); - if (ret < 0) - return ret; - return anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS); } diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.h b/drivers/gpu/drm/bridge/analogix/anx7625.h index 5af819611ebc..66ebee7f3d83 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.h +++ b/drivers/gpu/drm/bridge/analogix/anx7625.h @@ -259,6 +259,10 @@ #define AP_MIPI_RX_EN BIT(5) /* 1: MIPI RX input in 0: no RX in */ #define AP_DISABLE_PD BIT(6) #define AP_DISABLE_DISPLAY BIT(7) + +#define GPIO_CTRL_2 0x49 +#define HPD_SOURCEBIT(6) + /***/ /* Register definition of device address 0x84 */ #define MIPI_PHY_CONTROL_30x03 -- 2.43.0
[PATCH AUTOSEL 6.7 11/88] drm/panel-edp: Add override_edid_mode quirk for generic edp
From: Hsin-Yi Wang [ Upstream commit 9f7843b515811aea6c56527eb195b622e9c01f12 ] Generic edp gets mode from edid. However, some panels report incorrect mode in this way, resulting in glitches on panel. Introduce a new quirk additional_mode to the generic edid to pick a correct hardcoded mode. Signed-off-by: Hsin-Yi Wang Reviewed-by: Douglas Anderson Signed-off-by: Douglas Anderson Link: https://patchwork.freedesktop.org/patch/msgid/20231117215056.1883314-2-hsi...@chromium.org Signed-off-by: Sasha Levin --- drivers/gpu/drm/panel/panel-edp.c | 48 +-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c index 95c8472d878a..87a69293f594 100644 --- a/drivers/gpu/drm/panel/panel-edp.c +++ b/drivers/gpu/drm/panel/panel-edp.c @@ -203,6 +203,9 @@ struct edp_panel_entry { /** @name: Name of this panel (for printing to logs). */ const char *name; + + /** @override_edid_mode: Override the mode obtained by edid. */ + const struct drm_display_mode *override_edid_mode; }; struct panel_edp { @@ -301,6 +304,24 @@ static unsigned int panel_edp_get_display_modes(struct panel_edp *panel, return num; } +static int panel_edp_override_edid_mode(struct panel_edp *panel, + struct drm_connector *connector, + const struct drm_display_mode *override_mode) +{ + struct drm_display_mode *mode; + + mode = drm_mode_duplicate(connector->dev, override_mode); + if (!mode) { + dev_err(panel->base.dev, "failed to add additional mode\n"); + return 0; + } + + mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; + drm_mode_set_name(mode); + drm_mode_probed_add(connector, mode); + return 1; +} + static int panel_edp_get_non_edid_modes(struct panel_edp *panel, struct drm_connector *connector) { @@ -568,6 +589,9 @@ static int panel_edp_get_modes(struct drm_panel *panel, { struct panel_edp *p = to_panel_edp(panel); int num = 0; + bool has_override_edid_mode = p->detected_panel && + p->detected_panel != ERR_PTR(-EINVAL) && + p->detected_panel->override_edid_mode; /* probe EDID if a DDC bus is available */ if (p->ddc) { @@ -575,9 +599,18 @@ static int panel_edp_get_modes(struct drm_panel *panel, if (!p->edid) p->edid = drm_get_edid(connector, p->ddc); - - if (p->edid) - num += drm_add_edid_modes(connector, p->edid); + if (p->edid) { + if (has_override_edid_mode) { + /* +* override_edid_mode is specified. Use +* override_edid_mode instead of from edid. +*/ + num += panel_edp_override_edid_mode(p, connector, + p->detected_panel->override_edid_mode); + } else { + num += drm_add_edid_modes(connector, p->edid); + } + } pm_runtime_mark_last_busy(panel->dev); pm_runtime_put_autosuspend(panel->dev); @@ -1828,6 +1861,15 @@ static const struct panel_delay delay_200_500_e200 = { .delay = _delay \ } +#define EDP_PANEL_ENTRY2(vend_chr_0, vend_chr_1, vend_chr_2, product_id, _delay, _name, _mode) \ +{ \ + .name = _name, \ + .panel_id = drm_edid_encode_panel_id(vend_chr_0, vend_chr_1, vend_chr_2, \ +product_id), \ + .delay = _delay, \ + .override_edid_mode = _mode \ +} + /* * This table is used to figure out power sequencing delays for panels that * are detected by EDID. Entries here may point to entries in the -- 2.43.0
[PATCH AUTOSEL 6.7 13/88] drm/amd/display: Fix tiled display misalignment
From: Meenakshikumar Somasundaram [ Upstream commit c4b8394e76adba4f50a3c2696c75b214a291e24a ] [Why] When otg workaround is applied during clock update, otgs of tiled display went out of sync. [How] To call dc_trigger_sync() after clock update to sync otgs again. Reviewed-by: Nicholas Kazlauskas Acked-by: Hamza Mahfooz Signed-off-by: Meenakshikumar Somasundaram Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/display/dc/core/dc.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 5c1185206645..220f05975c0d 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1964,6 +1964,10 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c wait_for_no_pipes_pending(dc, context); /* pplib is notified if disp_num changed */ dc->hwss.optimize_bandwidth(dc, context); + /* Need to do otg sync again as otg could be out of sync due to otg +* workaround applied during clock update +*/ + dc_trigger_sync(dc, context); } if (dc->hwss.update_dsc_pg) -- 2.43.0
[PATCH AUTOSEL 6.7 18/88] drm/amd/display: Fix MST PBN/X.Y value calculations
From: Ilya Bakoulin [ Upstream commit 94bbf802efd0a8f13147d6664af6e653637340a8 ] Changing PBN calculation to be more in line with spec. We don't need to inflate PBN_NATIVE value by the 1.006 margin, since that is already taken care of in the get_pbn_per_slot function. Tested-by: Daniel Wheeler Reviewed-by: Wenjing Liu Acked-by: Rodrigo Siqueira Signed-off-by: Ilya Bakoulin Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/display/dc/link/link_dpms.c | 13 - 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c index f8e01ca09d96..a3b3aec05d6b 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c @@ -1057,18 +1057,21 @@ static struct fixed31_32 get_pbn_from_bw_in_kbps(uint64_t kbps) uint32_t denominator = 1; /* -* margin 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006 +* The 1.006 factor (margin 5300ppm + 300ppm ~ 0.6% as per spec) is not +* required when determining PBN/time slot utilization on the link between +* us and the branch, since that overhead is already accounted for in +* the get_pbn_per_slot function. +* * The unit of 54/64Mbytes/sec is an arbitrary unit chosen based on * common multiplier to render an integer PBN for all link rate/lane * counts combinations * calculate -* peak_kbps *= (1006/1000) * peak_kbps *= (64/54) -* peak_kbps *= 8convert to bytes +* peak_kbps /= (8 * 1000) convert to bytes */ - numerator = 64 * PEAK_FACTOR_X1000; - denominator = 54 * 8 * 1000 * 1000; + numerator = 64; + denominator = 54 * 8 * 1000; kbps *= numerator; peak_kbps = dc_fixpt_from_fraction(kbps, denominator); -- 2.43.0
[PATCH AUTOSEL 6.7 19/88] drm/amd/display: Fix disable_otg_wa logic
From: Nicholas Susanto [ Upstream commit 2ce156482a6fef349d2eba98e5070c412d3af662 ] [Why] When switching to another HDMI mode, we are unnecesarilly disabling/enabling FIFO causing both HPO and DIG registers to be set at the same time when only HPO is supposed to be set. This can lead to a system hang the next time we change refresh rates as there are cases when we don't disable OTG/FIFO but FIFO is enabled when it isn't supposed to be. [How] Removing the enable/disable FIFO entirely. Tested-by: Daniel Wheeler Reviewed-by: Nicholas Kazlauskas Acked-by: Rodrigo Siqueira Signed-off-by: Nicholas Susanto Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- .../gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c | 8 1 file changed, 8 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c index d5fde7d23fbf..f3b0af2c0295 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c @@ -126,21 +126,13 @@ static void dcn35_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state * continue; if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal) || !pipe->stream->link_enc)) { - struct stream_encoder *stream_enc = pipe->stream_res.stream_enc; - if (disable) { - if (stream_enc && stream_enc->funcs->disable_fifo) - pipe->stream_res.stream_enc->funcs->disable_fifo(stream_enc); - if (pipe->stream_res.tg && pipe->stream_res.tg->funcs->immediate_disable_crtc) pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg); reset_sync_context_for_pipe(dc, context, i); } else { pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg); - - if (stream_enc && stream_enc->funcs->enable_fifo) - pipe->stream_res.stream_enc->funcs->enable_fifo(stream_enc); } } } -- 2.43.0
[PATCH AUTOSEL 6.7 20/88] drm/amd/display: Fix Replay Desync Error IRQ handler
From: Dennis Chan [ Upstream commit dd5c6362ddcd8bdb07704faff8648593885ecfa1 ] In previous case, Replay didn't identify the IRQ type, This commit fixes the issues for the interrupt. Tested-by: Daniel Wheeler Reviewed-by: Robin Chen Acked-by: Rodrigo Siqueira Signed-off-by: Dennis Chan Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- .../display/dc/link/protocols/link_dp_irq_handler.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c index 0c00e94e90b1..9eadc2c7f221 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c @@ -190,9 +190,6 @@ static void handle_hpd_irq_replay_sink(struct dc_link *link) /*AMD Replay version reuse DP_PSR_ERROR_STATUS for REPLAY_ERROR status.*/ union psr_error_status replay_error_status; - if (link->replay_settings.config.force_disable_desync_error_check) - return; - if (!link->replay_settings.replay_feature_enabled) return; @@ -210,9 +207,6 @@ static void handle_hpd_irq_replay_sink(struct dc_link *link) &replay_error_status.raw, sizeof(replay_error_status.raw)); - if (replay_configuration.bits.DESYNC_ERROR_STATUS) - link->replay_settings.config.received_desync_error_hpd = 1; - link->replay_settings.config.replay_error_status.bits.LINK_CRC_ERROR = replay_error_status.bits.LINK_CRC_ERROR; link->replay_settings.config.replay_error_status.bits.DESYNC_ERROR = @@ -225,6 +219,12 @@ static void handle_hpd_irq_replay_sink(struct dc_link *link) link->replay_settings.config.replay_error_status.bits.STATE_TRANSITION_ERROR) { bool allow_active; + if (link->replay_settings.config.replay_error_status.bits.DESYNC_ERROR) + link->replay_settings.config.received_desync_error_hpd = 1; + + if (link->replay_settings.config.force_disable_desync_error_check) + return; + /* Acknowledge and clear configuration bits */ dm_helpers_dp_write_dpcd( link->ctx, -- 2.43.0
[PATCH AUTOSEL 6.7 17/88] drm/amd/display: initialize all the dpm level's stutter latency
From: Charlene Liu [ Upstream commit 885c71ad791c1709f668a37f701d33e6872a902f ] Fix issue when override level bigger than default. Levels 5, 6, and 7 had zero stutter latency, this is because override level being initialized after stutter latency inits. Tested-by: Daniel Wheeler Reviewed-by: Syed Hassan Reviewed-by: Allen Pan Acked-by: Rodrigo Siqueira Signed-off-by: Charlene Liu Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c index db06a5b749b4..279e7605a0a2 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c @@ -341,6 +341,9 @@ void dml2_init_soc_states(struct dml2_context *dml2, const struct dc *in_dc, break; } + if (dml2->config.bbox_overrides.clks_table.num_states) + p->in_states->num_states = dml2->config.bbox_overrides.clks_table.num_states; + /* Override from passed values, if available */ for (i = 0; i < p->in_states->num_states; i++) { if (dml2->config.bbox_overrides.sr_exit_latency_us) { @@ -397,7 +400,6 @@ void dml2_init_soc_states(struct dml2_context *dml2, const struct dc *in_dc, } /* Copy clocks tables entries, if available */ if (dml2->config.bbox_overrides.clks_table.num_states) { - p->in_states->num_states = dml2->config.bbox_overrides.clks_table.num_states; for (i = 0; i < dml2->config.bbox_overrides.clks_table.num_entries_per_clk.num_dcfclk_levels; i++) { p->in_states->state_array[i].dcfclk_mhz = dml2->config.bbox_overrides.clks_table.clk_entries[i].dcfclk_mhz; -- 2.43.0
[PATCH AUTOSEL 6.7 21/88] drm/amd/display: add support for DTO genarated dscclk
From: Wenjing Liu [ Upstream commit 08a32addf17317b9fac55be9b31275cbf6e41fb7 ] Current implementation will choose to use refclk as dscclk. This is not recommended by hardware team as refclk is a fixed value which could cause unnecessary power consumption or it could be not enough for large DSC timings. So we are adding new interfaces so we could switch to use dynamically generated DSCCLK by DTO. So DSCCLK is programmable based on current pixel clock and dispclk. Tested-by: Daniel Wheeler Reviewed-by: Chaitanya Dhere Acked-by: Rodrigo Siqueira Signed-off-by: Wenjing Liu Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- .../amd/display/dc/hwss/dcn32/dcn32_hwseq.c | 25 + drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h | 4 +++ .../gpu/drm/amd/display/dc/link/link_dpms.c | 27 ++- 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c index c1a9b746c43f..0f0972ad441a 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c @@ -995,9 +995,22 @@ static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream, static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable) { struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc; + struct dc *dc = pipe_ctx->stream->ctx->dc; struct dc_stream_state *stream = pipe_ctx->stream; struct pipe_ctx *odm_pipe; int opp_cnt = 1; + struct dccg *dccg = dc->res_pool->dccg; + /* It has been found that when DSCCLK is lower than 16Mhz, we will get DCN +* register access hung. When DSCCLk is based on refclk, DSCCLk is always a +* fixed value higher than 16Mhz so the issue doesn't occur. When DSCCLK is +* generated by DTO, DSCCLK would be based on 1/3 dispclk. For small timings +* with DSC such as 480p60Hz, the dispclk could be low enough to trigger +* this problem. We are implementing a workaround here to keep using dscclk +* based on fixed value refclk when timing is smaller than 3x16Mhz (i.e +* 48Mhz) pixel clock to avoid hitting this problem. +*/ + bool should_use_dto_dscclk = (dccg->funcs->set_dto_dscclk != NULL) && + stream->timing.pix_clk_100hz > 48; ASSERT(dsc); for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) @@ -1020,12 +1033,16 @@ static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable) dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg); dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst); + if (should_use_dto_dscclk) + dccg->funcs->set_dto_dscclk(dccg, dsc->inst); for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) { struct display_stream_compressor *odm_dsc = odm_pipe->stream_res.dsc; ASSERT(odm_dsc); odm_dsc->funcs->dsc_set_config(odm_dsc, &dsc_cfg, &dsc_optc_cfg); odm_dsc->funcs->dsc_enable(odm_dsc, odm_pipe->stream_res.opp->inst); + if (should_use_dto_dscclk) + dccg->funcs->set_dto_dscclk(dccg, odm_dsc->inst); } dsc_cfg.dc_dsc_cfg.num_slices_h *= opp_cnt; dsc_cfg.pic_width *= opp_cnt; @@ -1045,9 +1062,13 @@ static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable) OPTC_DSC_DISABLED, 0, 0); /* disable DSC block */ + if (dccg->funcs->set_ref_dscclk) + dccg->funcs->set_ref_dscclk(dccg, pipe_ctx->stream_res.dsc->inst); dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc); for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) { ASSERT(odm_pipe->stream_res.dsc); + if (dccg->funcs->set_ref_dscclk) + dccg->funcs->set_ref_dscclk(dccg, odm_pipe->stream_res.dsc->inst); odm_pipe->stream_res.dsc->funcs->dsc_disable(odm_pipe->stream_res.dsc); } } @@ -1130,6 +1151,10 @@ void dcn32_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx * if (!pipe_ctx->next_odm_pipe && current_pipe_ctx->next_odm_pipe && current_pipe_ctx->next_odm_pipe->stream_res.dsc) { struct display_stream_compressor *dsc = current_pipe_ctx->next_odm_pipe->stream_res.dsc; + struct dccg *dccg = dc->res_pool->dccg; + + if (dccg->funcs->set_ref_dscclk) +
[PATCH AUTOSEL 6.7 22/88] drm/amd/display: Fix writeback_info never got updated
From: Alex Hung [ Upstream commit c09919e6ea5fefd49d8b7b54aa5b222937163108 ] [WHY] wb_enabled field is set to false before it is used, and the following code will never be executed. [HOW] Setting wb_enable to false after all removal work is completed. Tested-by: Daniel Wheeler Reviewed-by: Harry Wentland Signed-off-by: Alex Hung Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 13 - 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index 4bdf105d1d71..5055af147c20 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -490,18 +490,13 @@ bool dc_stream_remove_writeback(struct dc *dc, return false; } -// stream->writeback_info[dwb_pipe_inst].wb_enabled = false; - for (i = 0; i < stream->num_wb_info; i++) { - /*dynamic update*/ - if (stream->writeback_info[i].wb_enabled && - stream->writeback_info[i].dwb_pipe_inst == dwb_pipe_inst) { - stream->writeback_info[i].wb_enabled = false; - } - } - /* remove writeback info for disabled writeback pipes from stream */ for (i = 0, j = 0; i < stream->num_wb_info; i++) { if (stream->writeback_info[i].wb_enabled) { + + if (stream->writeback_info[i].dwb_pipe_inst == dwb_pipe_inst) + stream->writeback_info[i].wb_enabled = false; + if (j < i) /* trim the array */ memcpy(&stream->writeback_info[j], &stream->writeback_info[i], -- 2.43.0
[PATCH AUTOSEL 6.7 24/88] drm/drm_file: fix use of uninitialized variable
From: Tomi Valkeinen [ Upstream commit 1d3062fad9c7313fff9970a88e0538a24480ffb8 ] smatch reports: drivers/gpu/drm/drm_file.c:967 drm_show_memory_stats() error: uninitialized symbol 'supported_status'. 'supported_status' is only set in one code path. I'm not familiar with the code to say if that path will always be ran in real life, but whether that is the case or not, I think it is good to initialize 'supported_status' to 0 to silence the warning (and possibly fix a bug). Reviewed-by: Laurent Pinchart Acked-by: Maxime Ripard Signed-off-by: Tomi Valkeinen Link: https://patchwork.freedesktop.org/patch/msgid/20231103-uninit-fixes-v2-1-c22b2444f...@ideasonboard.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/drm_file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index 446458aca8e9..54a7103c1c0f 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -958,7 +958,7 @@ void drm_show_memory_stats(struct drm_printer *p, struct drm_file *file) { struct drm_gem_object *obj; struct drm_memory_stats status = {}; - enum drm_gem_object_status supported_status; + enum drm_gem_object_status supported_status = 0; int id; spin_lock(&file->table_lock); -- 2.43.0
[PATCH AUTOSEL 6.7 25/88] drm/framebuffer: Fix use of uninitialized variable
From: Tomi Valkeinen [ Upstream commit f9af8f0c1dc567a5a6a6318ff324c45d80d4a60f ] smatch reports: drivers/gpu/drm/drm_framebuffer.c:654 drm_mode_getfb2_ioctl() error: uninitialized symbol 'ret'. 'ret' is possibly not set when there are no errors, causing the error above. I can't say if that ever happens in real-life, but in any case I think it is good to initialize 'ret' to 0. Reviewed-by: Laurent Pinchart Acked-by: Maxime Ripard Signed-off-by: Tomi Valkeinen Link: https://patchwork.freedesktop.org/patch/msgid/20231103-uninit-fixes-v2-2-c22b2444f...@ideasonboard.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/drm_framebuffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index d3ba0698b84b..36c5629af7d8 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -552,7 +552,7 @@ int drm_mode_getfb2_ioctl(struct drm_device *dev, struct drm_mode_fb_cmd2 *r = data; struct drm_framebuffer *fb; unsigned int i; - int ret; + int ret = 0; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; -- 2.43.0
[PATCH AUTOSEL 6.7 23/88] drm/amd/display: Fix writeback_info is not removed
From: Alex Hung [ Upstream commit ab37b88ed9de9de8d582683f7ea17059f1251a7f ] [WHY] Counter j was not updated to present the num of writeback_info when writeback pipes are removed. [HOW] update j (num of writeback info) under the correct condition. Tested-by: Daniel Wheeler Reviewed-by: Harry Wentland Signed-off-by: Alex Hung Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index 5055af147c20..37dc280e5566 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -497,11 +497,12 @@ bool dc_stream_remove_writeback(struct dc *dc, if (stream->writeback_info[i].dwb_pipe_inst == dwb_pipe_inst) stream->writeback_info[i].wb_enabled = false; - if (j < i) - /* trim the array */ + /* trim the array */ + if (j < i) { memcpy(&stream->writeback_info[j], &stream->writeback_info[i], sizeof(struct dc_writeback_info)); - j++; + j++; + } } } stream->num_wb_info = j; -- 2.43.0
[PATCH AUTOSEL 6.7 26/88] drm/mipi-dsi: Fix detach call without attach
From: Tomi Valkeinen [ Upstream commit 90d50b8d85834e73536fdccd5aa913b30494fef0 ] It's been reported that DSI host driver's detach can be called without the attach ever happening: https://lore.kernel.org/all/20230412073954.20601-1-t...@atomide.com/ After reading the code, I think this is what happens: We have a DSI host defined in the device tree and a DSI peripheral under that host (i.e. an i2c device using the DSI as data bus doesn't exhibit this behavior). The host driver calls mipi_dsi_host_register(), which causes (via a few functions) mipi_dsi_device_add() to be called for the DSI peripheral. So now we have a DSI device under the host, but attach hasn't been called. Normally the probing of the devices continues, and eventually the DSI peripheral's driver will call mipi_dsi_attach(), attaching the peripheral. However, if the host driver's probe encounters an error after calling mipi_dsi_host_register(), and before the peripheral has called mipi_dsi_attach(), the host driver will do cleanups and return an error from its probe function. The cleanups include calling mipi_dsi_host_unregister(). mipi_dsi_host_unregister() will call two functions for all its DSI peripheral devices: mipi_dsi_detach() and mipi_dsi_device_unregister(). The latter makes sense, as the device exists, but the former may be wrong as attach has not necessarily been done. To fix this, track the attached state of the peripheral, and only detach from mipi_dsi_host_unregister() if the peripheral was attached. Note that I have only tested this with a board with an i2c DSI peripheral, not with a "pure" DSI peripheral. However, slightly related, the unregister machinery still seems broken. E.g. if the DSI host driver is unbound, it'll detach and unregister the DSI peripherals. After that, when the DSI peripheral driver unbound it'll call detach either directly or using the devm variant, leading to a crash. And probably the driver will crash if it happens, for some reason, to try to send a message via the DSI bus. But that's another topic. Tested-by: H. Nikolaus Schaller Acked-by: Maxime Ripard Reviewed-by: Sebastian Reichel Tested-by: Tony Lindgren Signed-off-by: Tomi Valkeinen Link: https://patchwork.freedesktop.org/patch/msgid/20230921-dsi-detach-fix-v1-1-d0de2d162...@ideasonboard.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/drm_mipi_dsi.c | 17 +++-- include/drm/drm_mipi_dsi.h | 2 ++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 14201f73aab1..843a6dbda93a 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -347,7 +347,8 @@ static int mipi_dsi_remove_device_fn(struct device *dev, void *priv) { struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); - mipi_dsi_detach(dsi); + if (dsi->attached) + mipi_dsi_detach(dsi); mipi_dsi_device_unregister(dsi); return 0; @@ -370,11 +371,18 @@ EXPORT_SYMBOL(mipi_dsi_host_unregister); int mipi_dsi_attach(struct mipi_dsi_device *dsi) { const struct mipi_dsi_host_ops *ops = dsi->host->ops; + int ret; if (!ops || !ops->attach) return -ENOSYS; - return ops->attach(dsi->host, dsi); + ret = ops->attach(dsi->host, dsi); + if (ret) + return ret; + + dsi->attached = true; + + return 0; } EXPORT_SYMBOL(mipi_dsi_attach); @@ -386,9 +394,14 @@ int mipi_dsi_detach(struct mipi_dsi_device *dsi) { const struct mipi_dsi_host_ops *ops = dsi->host->ops; + if (WARN_ON(!dsi->attached)) + return -EINVAL; + if (!ops || !ops->detach) return -ENOSYS; + dsi->attached = false; + return ops->detach(dsi->host, dsi); } EXPORT_SYMBOL(mipi_dsi_detach); diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index c9df0407980c..c0aec0d4d664 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -168,6 +168,7 @@ struct mipi_dsi_device_info { * struct mipi_dsi_device - DSI peripheral device * @host: DSI host for this peripheral * @dev: driver model device node for this peripheral + * @attached: the DSI device has been successfully attached * @name: DSI peripheral chip type * @channel: virtual channel assigned to the peripheral * @format: pixel format for video mode @@ -184,6 +185,7 @@ struct mipi_dsi_device_info { struct mipi_dsi_device { struct mipi_dsi_host *host; struct device dev; + bool attached; char name[DSI_DEV_NAME_SIZE]; unsigned int channel; -- 2.43.0
[PATCH AUTOSEL 6.7 32/88] drm/msm/dp: Add DisplayPort controller for SM8650
From: Neil Armstrong [ Upstream commit 1b2d98bdd7b7c64265732f5f0dace4c52c9ba8a8 ] The Qualcomm SM8650 platform comes with a DisplayPort controller with a different base offset than the previous SM8550 SoC, add support for this in the DisplayPort driver. Signed-off-by: Neil Armstrong Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/571132/ Link: https://lore.kernel.org/r/20231207-topic-sm8650-upstream-dp-v1-2-b762c0696...@linaro.org Signed-off-by: Dmitry Baryshkov Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/dp/dp_display.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 1b88fb52726f..4f89c9939501 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -170,6 +170,11 @@ static const struct msm_dp_desc sm8350_dp_descs[] = { {} }; +static const struct msm_dp_desc sm8650_dp_descs[] = { + { .io_start = 0x0af54000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, + {} +}; + static const struct of_device_id dp_dt_match[] = { { .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_descs }, { .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_descs }, @@ -180,6 +185,7 @@ static const struct of_device_id dp_dt_match[] = { { .compatible = "qcom,sc8280xp-edp", .data = &sc8280xp_edp_descs }, { .compatible = "qcom,sdm845-dp", .data = &sc7180_dp_descs }, { .compatible = "qcom,sm8350-dp", .data = &sm8350_dp_descs }, + { .compatible = "qcom,sm8650-dp", .data = &sm8650_dp_descs }, {} }; -- 2.43.0
[PATCH AUTOSEL 6.7 50/88] drm/amd/display: For prefetch mode > 0, extend prefetch if possible
From: Alvin Lee [ Upstream commit dd4e4bb28843393065eed279e869fac248d03f0f ] [Description] For mode programming we want to extend the prefetch as much as possible (up to oto, or as long as we can for equ) if we're not already applying the 60us prefetch requirement. This is to avoid intermittent underflow issues during prefetch. The prefetch extension is applied under the following scenarios: 1. We're in prefetch mode 1 (i.e. we don't support MCLK switch in blank) 2. We're using subvp or drr methods of p-state switch, in which case we we don't care if prefetch takes up more of the blanking time Mode programming typically chooses the smallest prefetch time possible (i.e. highest bandwidth during prefetch) presumably to create margin between p-states / c-states that happen in vblank and prefetch. Therefore we only apply this prefetch extension when p-state in vblank is not required (UCLK p-states take up the most vblank time). Reviewed-by: Jun Lei Acked-by: Aurabindo Pillai Signed-off-by: Alvin Lee Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- .../dc/dml/dcn32/display_mode_vba_32.c| 3 ++ .../dc/dml/dcn32/display_mode_vba_util_32.c | 33 +++ .../dc/dml/dcn32/display_mode_vba_util_32.h | 1 + 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c index cbdfb762c10c..6c84b0fa40f4 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c @@ -813,6 +813,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman (v->DRAMSpeedPerState[mode_lib->vba.VoltageLevel] <= MEM_STROBE_FREQ_MHZ || v->DCFCLKPerState[mode_lib->vba.VoltageLevel] <= DCFCLK_FREQ_EXTRA_PREFETCH_REQ_MHZ) ? mode_lib->vba.ip.min_prefetch_in_strobe_us : 0, + mode_lib->vba.PrefetchModePerState[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb] > 0 || mode_lib->vba.DRAMClockChangeRequirementFinal == false, + /* Output */ &v->DSTXAfterScaler[k], &v->DSTYAfterScaler[k], @@ -3317,6 +3319,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l v->SwathHeightCThisState[k], v->TWait, (v->DRAMSpeedPerState[i] <= MEM_STROBE_FREQ_MHZ || v->DCFCLKState[i][j] <= DCFCLK_FREQ_EXTRA_PREFETCH_REQ_MHZ) ? mode_lib->vba.ip.min_prefetch_in_strobe_us : 0, + mode_lib->vba.PrefetchModePerState[i][j] > 0 || mode_lib->vba.DRAMClockChangeRequirementFinal == false, /* Output */ &v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.DSTXAfterScaler[k], diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c index d940dfa5ae43..80fccd4999a5 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c @@ -3423,6 +3423,7 @@ bool dml32_CalculatePrefetchSchedule( unsigned int SwathHeightC, double TWait, double TPreReq, + bool ExtendPrefetchIfPossible, /* Output */ double *DSTXAfterScaler, double *DSTYAfterScaler, @@ -3892,12 +3893,32 @@ bool dml32_CalculatePrefetchSchedule( /* Clamp to oto for bandwidth calculation */ LinesForPrefetchBandwidth = dst_y_prefetch_oto; } else { - *DestinationLinesForPrefetch = dst_y_prefetch_equ; - TimeForFetchingMetaPTE = Tvm_equ; - TimeForFetchingRowInVBlank = Tr0_equ; - *PrefetchBandwidth = prefetch_bw_equ; - /* Clamp to equ for bandwidth calculation */ - LinesForPrefetchBandwidth = dst_y_prefetch_equ; + /* For mode programming we want to extend the prefetch as much as possible +* (up to oto, or as long as we can for equ) if we're not already applying +* the 60us prefetch requirement. This is to avoid intermittent underflow +* issues during prefetch. +
[PATCH AUTOSEL 6.7 44/88] drm/exynos: Call drm_atomic_helper_shutdown() at shutdown/unbind time
From: Douglas Anderson [ Upstream commit 16ac5b21b31b439f03cdf44c153c5f5af94fb3eb ] Based on grepping through the source code this driver appears to be missing a call to drm_atomic_helper_shutdown() at system shutdown time and at driver unbind time. Among other things, this means that if a panel is in use that it won't be cleanly powered off at system shutdown time. The fact that we should call drm_atomic_helper_shutdown() in the case of OS shutdown/restart and at driver remove (or unbind) time comes straight out of the kernel doc "driver instance overview" in drm_drv.c. A few notes about this fix: - When adding drm_atomic_helper_shutdown() to the unbind path, I added it after drm_kms_helper_poll_fini() since that's when other drivers seemed to have it. - Technically with a previous patch, ("drm/atomic-helper: drm_atomic_helper_shutdown(NULL) should be a noop"), we don't actually need to check to see if our "drm" pointer is NULL before calling drm_atomic_helper_shutdown(). We'll leave the "if" test in, though, so that this patch can land without any dependencies. It could potentially be removed later. - This patch also makes sure to set the drvdata to NULL in the case of bind errors to make sure that shutdown can't access freed data. Suggested-by: Maxime Ripard Reviewed-by: Maxime Ripard Signed-off-by: Douglas Anderson Tested-by: Marek Szyprowski Reviewed-by: Marek Szyprowski Signed-off-by: Inki Dae Signed-off-by: Sasha Levin --- drivers/gpu/drm/exynos/exynos_drm_drv.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 8399256cb5c9..5380fb6c55ae 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -300,6 +300,7 @@ static int exynos_drm_bind(struct device *dev) drm_mode_config_cleanup(drm); exynos_drm_cleanup_dma(drm); kfree(private); + dev_set_drvdata(dev, NULL); err_free_drm: drm_dev_put(drm); @@ -313,6 +314,7 @@ static void exynos_drm_unbind(struct device *dev) drm_dev_unregister(drm); drm_kms_helper_poll_fini(drm); + drm_atomic_helper_shutdown(drm); component_unbind_all(drm->dev, drm); drm_mode_config_cleanup(drm); @@ -350,9 +352,18 @@ static int exynos_drm_platform_remove(struct platform_device *pdev) return 0; } +static void exynos_drm_platform_shutdown(struct platform_device *pdev) +{ + struct drm_device *drm = platform_get_drvdata(pdev); + + if (drm) + drm_atomic_helper_shutdown(drm); +} + static struct platform_driver exynos_drm_platform_driver = { .probe = exynos_drm_platform_probe, .remove = exynos_drm_platform_remove, + .shutdown = exynos_drm_platform_shutdown, .driver = { .name = "exynos-drm", .pm = &exynos_drm_pm_ops, -- 2.43.0
[PATCH AUTOSEL 6.7 52/88] drm/amdkfd: fix mes set shader debugger process management
From: Jonathan Kim [ Upstream commit bd33bb1409b494558a2935f7bbc7842def957fcd ] MES provides the driver a call to explicitly flush stale process memory within the MES to avoid a race condition that results in a fatal memory violation. When SET_SHADER_DEBUGGER is called, the driver passes a memory address that represents a process context address MES uses to keep track of future per-process calls. Normally, MES will purge its process context list when the last queue has been removed. The driver, however, can call SET_SHADER_DEBUGGER regardless of whether a queue has been added or not. If SET_SHADER_DEBUGGER has been called with no queues as the last call prior to process termination, the passed process context address will still reside within MES. On a new process call to SET_SHADER_DEBUGGER, the driver may end up passing an identical process context address value (based on per-process gpu memory address) to MES but is now pointing to a new allocated buffer object during KFD process creation. Since the MES is unaware of this, access of the passed address points to the stale object within MES and triggers a fatal memory violation. The solution is for KFD to explicitly flush the process context address from MES on process termination. Note that the flush call and the MES debugger calls use the same MES interface but are separated as KFD calls to avoid conflicting with each other. Signed-off-by: Jonathan Kim Tested-by: Alice Wong Reviewed-by: Eric Huang Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 31 +++ drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h | 10 +++--- .../amd/amdkfd/kfd_process_queue_manager.c| 1 + drivers/gpu/drm/amd/include/mes_v11_api_def.h | 3 +- 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c index 9ddbf1494326..30c010836658 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c @@ -886,6 +886,11 @@ int amdgpu_mes_set_shader_debugger(struct amdgpu_device *adev, op_input.op = MES_MISC_OP_SET_SHADER_DEBUGGER; op_input.set_shader_debugger.process_context_addr = process_context_addr; op_input.set_shader_debugger.flags.u32all = flags; + + /* use amdgpu mes_flush_shader_debugger instead */ + if (op_input.set_shader_debugger.flags.process_ctx_flush) + return -EINVAL; + op_input.set_shader_debugger.spi_gdbg_per_vmid_cntl = spi_gdbg_per_vmid_cntl; memcpy(op_input.set_shader_debugger.tcp_watch_cntl, tcp_watch_cntl, sizeof(op_input.set_shader_debugger.tcp_watch_cntl)); @@ -905,6 +910,32 @@ int amdgpu_mes_set_shader_debugger(struct amdgpu_device *adev, return r; } +int amdgpu_mes_flush_shader_debugger(struct amdgpu_device *adev, +uint64_t process_context_addr) +{ + struct mes_misc_op_input op_input = {0}; + int r; + + if (!adev->mes.funcs->misc_op) { + DRM_ERROR("mes flush shader debugger is not supported!\n"); + return -EINVAL; + } + + op_input.op = MES_MISC_OP_SET_SHADER_DEBUGGER; + op_input.set_shader_debugger.process_context_addr = process_context_addr; + op_input.set_shader_debugger.flags.process_ctx_flush = true; + + amdgpu_mes_lock(&adev->mes); + + r = adev->mes.funcs->misc_op(&adev->mes, &op_input); + if (r) + DRM_ERROR("failed to set_shader_debugger\n"); + + amdgpu_mes_unlock(&adev->mes); + + return r; +} + static void amdgpu_mes_ring_to_queue_props(struct amdgpu_device *adev, struct amdgpu_ring *ring, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h index a27b424ffe00..c2c88b772361 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h @@ -291,9 +291,10 @@ struct mes_misc_op_input { uint64_t process_context_addr; union { struct { - uint64_t single_memop : 1; - uint64_t single_alu_op : 1; - uint64_t reserved: 30; + uint32_t single_memop : 1; + uint32_t single_alu_op : 1; + uint32_t reserved: 29; + uint32_t process_ctx_flush: 1; }; uint32_t u32all; } flags; @@ -369,7 +370,8 @@ int amdgpu_mes_set_shader_debugger(struct amdgpu_device *adev, const uint32_t *tcp_watch_cntl, uint32_t flags,
[PATCH AUTOSEL 6.7 54/88] drm/msm/dpu: enable writeback on SM8450
From: Dmitry Baryshkov [ Upstream commit eaa647cdbf2e357b4a14903f2f1e47ed9c4f8df3 ] Enable WB2 hardware block, enabling writeback support on this platform. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/570187/ Link: https://lore.kernel.org/r/20231203002743.1291956-4-dmitry.barysh...@linaro.org Signed-off-by: Sasha Levin --- .../drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 18 ++ 1 file changed, 18 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h index 7742f52be859..562de67103bb 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h @@ -32,6 +32,7 @@ static const struct dpu_mdp_cfg sm8450_mdp = { [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, [DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, + [DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 }, [DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, }, }; @@ -316,6 +317,21 @@ static const struct dpu_dsc_cfg sm8450_dsc[] = { }, }; +static const struct dpu_wb_cfg sm8450_wb[] = { + { + .name = "wb_2", .id = WB_2, + .base = 0x65000, .len = 0x2c8, + .features = WB_SM8250_MASK, + .format_list = wb2_formats, + .num_formats = ARRAY_SIZE(wb2_formats), + .clk_ctrl = DPU_CLK_CTRL_WB2, + .xin_id = 6, + .vbif_idx = VBIF_RT, + .maxlinewidth = 4096, + .intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4), + }, +}; + static const struct dpu_intf_cfg sm8450_intf[] = { { .name = "intf_0", .id = INTF_0, @@ -411,6 +427,8 @@ const struct dpu_mdss_cfg dpu_sm8450_cfg = { .dsc = sm8450_dsc, .merge_3d_count = ARRAY_SIZE(sm8450_merge_3d), .merge_3d = sm8450_merge_3d, + .wb_count = ARRAY_SIZE(sm8450_wb), + .wb = sm8450_wb, .intf_count = ARRAY_SIZE(sm8450_intf), .intf = sm8450_intf, .vbif_count = ARRAY_SIZE(sdm845_vbif), -- 2.43.0
[PATCH AUTOSEL 6.7 56/88] drm/msm/dpu: fix writeback programming for YUV cases
From: Abhinav Kumar [ Upstream commit 79caf2f2202b9eaad3a5a726e4b33807f67d0f1b ] For YUV cases, setting the required format bits was missed out in the register programming. Lets fix it now in preparation of adding YUV formats support for writeback. changes in v2: - dropped the fixes tag as its not a fix but adding new functionality Signed-off-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/571814/ Link: https://lore.kernel.org/r/20231212205254.12422-4-quic_abhin...@quicinc.com Signed-off-by: Dmitry Baryshkov Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c index 9668fb97c047..d49b3ef7689e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c @@ -87,6 +87,9 @@ static void dpu_hw_wb_setup_format(struct dpu_hw_wb *ctx, dst_format |= BIT(14); /* DST_ALPHA_X */ } + if (DPU_FORMAT_IS_YUV(fmt)) + dst_format |= BIT(15); + pattern = (fmt->element[3] << 24) | (fmt->element[2] << 16) | (fmt->element[1] << 8) | -- 2.43.0
[PATCH AUTOSEL 6.7 51/88] drm/amd/display: Force p-state disallow if leaving no plane config
From: Alvin Lee [ Upstream commit 9a902a9073c287353e25913c0761bfed49d75a88 ] [Description] - When we're in a no plane config, DCN is always asserting P-State allow - This creates a scenario where the P-State blackout can start just as VUPDATE takes place and transitions the DCN config to a one where one or more HUBP's are active which can result in underflow - To fix this issue, force p-state disallow and unforce after the transition from no planes case -> one or more planes active Reviewed-by: Samson Tam Acked-by: Aurabindo Pillai Signed-off-by: Alvin Lee Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- .../amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 20 +++ 1 file changed, 20 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c index 608221b0dd5d..c3c83178eb1e 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c @@ -1877,6 +1877,8 @@ void dcn20_program_front_end_for_ctx( int i; struct dce_hwseq *hws = dc->hwseq; DC_LOGGER_INIT(dc->ctx->logger); + unsigned int prev_hubp_count = 0; + unsigned int hubp_count = 0; if (resource_is_pipe_topology_changed(dc->current_state, context)) resource_log_pipe_topology_update(dc, context); @@ -1894,6 +1896,20 @@ void dcn20_program_front_end_for_ctx( } } + for (i = 0; i < dc->res_pool->pipe_count; i++) { + if (dc->current_state->res_ctx.pipe_ctx[i].plane_state) + prev_hubp_count++; + if (context->res_ctx.pipe_ctx[i].plane_state) + hubp_count++; + } + + if (prev_hubp_count == 0 && hubp_count > 0) { + if (dc->res_pool->hubbub->funcs->force_pstate_change_control) + dc->res_pool->hubbub->funcs->force_pstate_change_control( + dc->res_pool->hubbub, true, false); + udelay(500); + } + /* Set pipe update flags and lock pipes */ for (i = 0; i < dc->res_pool->pipe_count; i++) dcn20_detect_pipe_changes(&dc->current_state->res_ctx.pipe_ctx[i], @@ -2039,6 +2055,10 @@ void dcn20_post_unlock_program_front_end( } } + if (dc->res_pool->hubbub->funcs->force_pstate_change_control) + dc->res_pool->hubbub->funcs->force_pstate_change_control( + dc->res_pool->hubbub, false, false); + for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; -- 2.43.0
[PATCH AUTOSEL 6.7 53/88] drm/msm/dpu: enable writeback on SM8350
From: Dmitry Baryshkov [ Upstream commit c2949a49dfe960e952400029e14751dceff79d38 ] Enable WB2 hardware block, enabling writeback support on this platform. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/570188/ Link: https://lore.kernel.org/r/20231203002743.1291956-3-dmitry.barysh...@linaro.org Signed-off-by: Sasha Levin --- .../drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 18 ++ 1 file changed, 18 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h index 1709ba57f384..022b0408c24d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h @@ -31,6 +31,7 @@ static const struct dpu_mdp_cfg sm8350_mdp = { [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, [DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, + [DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 }, [DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, }, }; @@ -298,6 +299,21 @@ static const struct dpu_dsc_cfg sm8350_dsc[] = { }, }; +static const struct dpu_wb_cfg sm8350_wb[] = { + { + .name = "wb_2", .id = WB_2, + .base = 0x65000, .len = 0x2c8, + .features = WB_SM8250_MASK, + .format_list = wb2_formats, + .num_formats = ARRAY_SIZE(wb2_formats), + .clk_ctrl = DPU_CLK_CTRL_WB2, + .xin_id = 6, + .vbif_idx = VBIF_RT, + .maxlinewidth = 4096, + .intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4), + }, +}; + static const struct dpu_intf_cfg sm8350_intf[] = { { .name = "intf_0", .id = INTF_0, @@ -393,6 +409,8 @@ const struct dpu_mdss_cfg dpu_sm8350_cfg = { .dsc = sm8350_dsc, .merge_3d_count = ARRAY_SIZE(sm8350_merge_3d), .merge_3d = sm8350_merge_3d, + .wb_count = ARRAY_SIZE(sm8350_wb), + .wb = sm8350_wb, .intf_count = ARRAY_SIZE(sm8350_intf), .intf = sm8350_intf, .vbif_count = ARRAY_SIZE(sdm845_vbif), -- 2.43.0
[PATCH AUTOSEL 6.7 55/88] drm/msm/dpu: Ratelimit framedone timeout msgs
From: Rob Clark [ Upstream commit 2b72e50c62de60ad2d6bcd86aa38d4ccbdd633f2 ] When we start getting these, we get a *lot*. So ratelimit it to not flood dmesg. Signed-off-by: Rob Clark Reviewed-by: Abhinav Kumar Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/571584/ Link: https://lore.kernel.org/r/20231211182000.218088-1-robdcl...@gmail.com Signed-off-by: Dmitry Baryshkov Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 5 - drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 1cf7ff6caff4..ff0e3591b44d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -39,6 +39,9 @@ #define DPU_ERROR_ENC(e, fmt, ...) DPU_ERROR("enc%d " fmt,\ (e) ? (e)->base.base.id : -1, ##__VA_ARGS__) +#define DPU_ERROR_ENC_RATELIMITED(e, fmt, ...) DPU_ERROR_RATELIMITED("enc%d " fmt,\ + (e) ? (e)->base.base.id : -1, ##__VA_ARGS__) + /* * Two to anticipate panels that can do cmd/vid dynamic switching * plan is to create all possible physical encoder types, and switch between @@ -2339,7 +2342,7 @@ static void dpu_encoder_frame_done_timeout(struct timer_list *t) return; } - DPU_ERROR_ENC(dpu_enc, "frame done timeout\n"); + DPU_ERROR_ENC_RATELIMITED(dpu_enc, "frame done timeout\n"); event = DPU_ENCODER_FRAME_EVENT_ERROR; trace_dpu_enc_frame_done_timeout(DRMID(drm_enc), event); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index b6f53ca6e962..f5473d4dea92 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -51,6 +51,7 @@ } while (0) #define DPU_ERROR(fmt, ...) pr_err("[dpu error]" fmt, ##__VA_ARGS__) +#define DPU_ERROR_RATELIMITED(fmt, ...) pr_err_ratelimited("[dpu error]" fmt, ##__VA_ARGS__) /** * ktime_compare_safe - compare two ktime structures -- 2.43.0
[PATCH AUTOSEL 6.7 63/88] accel/habanalabs: add support for Gaudi2C device
From: Oded Gabbay [ Upstream commit 42422993cf28d456778ee9168d73758ec037cd51 ] Gaudi2 with PCI revision ID with the value of '3' represents Gaudi2C device and should be detected and initialized as Gaudi2. Signed-off-by: Oded Gabbay Signed-off-by: Sasha Levin --- drivers/accel/habanalabs/common/device.c | 3 +++ drivers/accel/habanalabs/common/habanalabs.h | 2 ++ drivers/accel/habanalabs/common/habanalabs_drv.c | 3 +++ drivers/accel/habanalabs/common/mmu/mmu.c| 1 + drivers/accel/habanalabs/common/sysfs.c | 3 +++ drivers/accel/habanalabs/include/hw_ip/pci/pci_general.h | 1 + 6 files changed, 13 insertions(+) diff --git a/drivers/accel/habanalabs/common/device.c b/drivers/accel/habanalabs/common/device.c index 9711e8fc979d..9e461c03e705 100644 --- a/drivers/accel/habanalabs/common/device.c +++ b/drivers/accel/habanalabs/common/device.c @@ -853,6 +853,9 @@ static int device_early_init(struct hl_device *hdev) gaudi2_set_asic_funcs(hdev); strscpy(hdev->asic_name, "GAUDI2B", sizeof(hdev->asic_name)); break; + case ASIC_GAUDI2C: + gaudi2_set_asic_funcs(hdev); + strscpy(hdev->asic_name, "GAUDI2C", sizeof(hdev->asic_name)); break; default: dev_err(hdev->dev, "Unrecognized ASIC type %d\n", diff --git a/drivers/accel/habanalabs/common/habanalabs.h b/drivers/accel/habanalabs/common/habanalabs.h index 1655c101c705..d0fd77bb6a74 100644 --- a/drivers/accel/habanalabs/common/habanalabs.h +++ b/drivers/accel/habanalabs/common/habanalabs.h @@ -1262,6 +1262,7 @@ struct hl_dec { * @ASIC_GAUDI_SEC: Gaudi secured device (HL-2000). * @ASIC_GAUDI2: Gaudi2 device. * @ASIC_GAUDI2B: Gaudi2B device. + * @ASIC_GAUDI2C: Gaudi2C device. */ enum hl_asic_type { ASIC_INVALID, @@ -1270,6 +1271,7 @@ enum hl_asic_type { ASIC_GAUDI_SEC, ASIC_GAUDI2, ASIC_GAUDI2B, + ASIC_GAUDI2C, }; struct hl_cs_parser; diff --git a/drivers/accel/habanalabs/common/habanalabs_drv.c b/drivers/accel/habanalabs/common/habanalabs_drv.c index 306a5bc9bf89..51fb04bbe376 100644 --- a/drivers/accel/habanalabs/common/habanalabs_drv.c +++ b/drivers/accel/habanalabs/common/habanalabs_drv.c @@ -141,6 +141,9 @@ static enum hl_asic_type get_asic_type(struct hl_device *hdev) case REV_ID_B: asic_type = ASIC_GAUDI2B; break; + case REV_ID_C: + asic_type = ASIC_GAUDI2C; + break; default: break; } diff --git a/drivers/accel/habanalabs/common/mmu/mmu.c b/drivers/accel/habanalabs/common/mmu/mmu.c index b2145716c605..b654302a68fc 100644 --- a/drivers/accel/habanalabs/common/mmu/mmu.c +++ b/drivers/accel/habanalabs/common/mmu/mmu.c @@ -596,6 +596,7 @@ int hl_mmu_if_set_funcs(struct hl_device *hdev) break; case ASIC_GAUDI2: case ASIC_GAUDI2B: + case ASIC_GAUDI2C: /* MMUs in Gaudi2 are always host resident */ hl_mmu_v2_hr_set_funcs(hdev, &hdev->mmu_func[MMU_HR_PGT]); break; diff --git a/drivers/accel/habanalabs/common/sysfs.c b/drivers/accel/habanalabs/common/sysfs.c index 01f89f029355..278606373055 100644 --- a/drivers/accel/habanalabs/common/sysfs.c +++ b/drivers/accel/habanalabs/common/sysfs.c @@ -251,6 +251,9 @@ static ssize_t device_type_show(struct device *dev, case ASIC_GAUDI2B: str = "GAUDI2B"; break; + case ASIC_GAUDI2C: + str = "GAUDI2C"; + break; default: dev_err(hdev->dev, "Unrecognized ASIC type %d\n", hdev->asic_type); diff --git a/drivers/accel/habanalabs/include/hw_ip/pci/pci_general.h b/drivers/accel/habanalabs/include/hw_ip/pci/pci_general.h index f5d497dc9bdc..4f951cada077 100644 --- a/drivers/accel/habanalabs/include/hw_ip/pci/pci_general.h +++ b/drivers/accel/habanalabs/include/hw_ip/pci/pci_general.h @@ -25,6 +25,7 @@ enum hl_revision_id { REV_ID_INVALID = 0x00, REV_ID_A= 0x01, REV_ID_B= 0x02, + REV_ID_C= 0x03 }; #endif /* INCLUDE_PCI_GENERAL_H_ */ -- 2.43.0
[PATCH AUTOSEL 6.7 57/88] drm/msm/dpu: Add mutex lock in control vblank irq
From: Paloma Arellano [ Upstream commit 45284ff733e4caf6c118aae5131eb7e7cf3eea5a ] Add a mutex lock to control vblank irq to synchronize vblank enable/disable operations happening from different threads to prevent race conditions while registering/unregistering the vblank irq callback. v4: -Removed vblank_ctl_lock from dpu_encoder_virt, so it is only a parameter of dpu_encoder_phys. -Switch from atomic refcnt to a simple int counter as mutex has now been added v3: Mistakenly did not change wording in last version. It is done now. v2: Slightly changed wording of commit message Signed-off-by: Paloma Arellano Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/571854/ Link: https://lore.kernel.org/r/20231212231101.9240-2-quic_parel...@quicinc.com Signed-off-by: Dmitry Baryshkov Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 1 - .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 4 ++- .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 32 -- .../drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 33 --- 4 files changed, 47 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index ff0e3591b44d..289e4a615a08 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -2500,7 +2500,6 @@ void dpu_encoder_phys_init(struct dpu_encoder_phys *phys_enc, phys_enc->enc_spinlock = p->enc_spinlock; phys_enc->enable_state = DPU_ENC_DISABLED; - atomic_set(&phys_enc->vblank_refcount, 0); atomic_set(&phys_enc->pending_kickoff_cnt, 0); atomic_set(&phys_enc->pending_ctlstart_cnt, 0); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h index 6f04c3d56e77..96bda57b6959 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -155,6 +155,7 @@ enum dpu_intr_idx { * @hw_wb: Hardware interface to the wb registers * @dpu_kms: Pointer to the dpu_kms top level * @cached_mode: DRM mode cached at mode_set time, acted on in enable + * @vblank_ctl_lock: Vblank ctl mutex lock to protect vblank_refcount * @enabled: Whether the encoder has enabled and running a mode * @split_role:Role to play in a split-panel configuration * @intf_mode: Interface mode @@ -183,11 +184,12 @@ struct dpu_encoder_phys { struct dpu_hw_wb *hw_wb; struct dpu_kms *dpu_kms; struct drm_display_mode cached_mode; + struct mutex vblank_ctl_lock; enum dpu_enc_split_role split_role; enum dpu_intf_mode intf_mode; spinlock_t *enc_spinlock; enum dpu_enc_enable_state enable_state; - atomic_t vblank_refcount; + int vblank_refcount; atomic_t vsync_cnt; atomic_t underrun_cnt; atomic_t pending_ctlstart_cnt; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index be185fe69793..2d788c5e26a8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -244,7 +244,8 @@ static int dpu_encoder_phys_cmd_control_vblank_irq( return -EINVAL; } - refcount = atomic_read(&phys_enc->vblank_refcount); + mutex_lock(&phys_enc->vblank_ctl_lock); + refcount = phys_enc->vblank_refcount; /* Slave encoders don't report vblank */ if (!dpu_encoder_phys_cmd_is_master(phys_enc)) @@ -260,16 +261,24 @@ static int dpu_encoder_phys_cmd_control_vblank_irq( phys_enc->hw_pp->idx - PINGPONG_0, enable ? "true" : "false", refcount); - if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1) - ret = dpu_core_irq_register_callback(phys_enc->dpu_kms, - phys_enc->irq[INTR_IDX_RDPTR], - dpu_encoder_phys_cmd_te_rd_ptr_irq, - phys_enc); - else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0) - ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms, - phys_enc->irq[INTR_IDX_RDPTR]); + if (enable) { + if (phys_enc->vblank_refcount == 0) + ret = dpu_core_irq_register_callback(phys_enc->dpu_kms, + phys_enc->irq[INTR_IDX_RDPTR], + dpu_encoder_phys_cmd_te_rd_ptr_irq, + phys_enc); + if (!ret) + phys_enc->vblank_refcount++; + } else if (!enable) { + if (phys_enc->vblank_refcount == 1) + ret = dpu_core_irq_
[PATCH AUTOSEL 6.7 67/88] drm/amd/display: fix usb-c connector_type
From: Allen Pan [ Upstream commit 0d26644bc57d8737c8e2fb3145366f7d0b941935 ] [why] BIOS switches to use USB-C connector type 0x18, but VBIOS's objectInfo table not supported yet. driver needs to patch it based on enc_cap from system integration info table. Reviewed-by: Charlene Liu Acked-by: Wayne Lin Signed-off-by: Allen Pan Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- .../gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c| 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c index f91e08895275..da94e5309fba 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c @@ -256,6 +256,10 @@ void dcn35_link_encoder_construct( enc10->base.features.flags.bits.IS_UHBR10_CAPABLE = bp_cap_info.DP_UHBR10_EN; enc10->base.features.flags.bits.IS_UHBR13_5_CAPABLE = bp_cap_info.DP_UHBR13_5_EN; enc10->base.features.flags.bits.IS_UHBR20_CAPABLE = bp_cap_info.DP_UHBR20_EN; + if (bp_cap_info.DP_IS_USB_C) { + /*BIOS not switch to use CONNECTOR_ID_USBC = 24 yet*/ + enc10->base.features.flags.bits.DP_IS_USB_C = 1; + } } else { DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n", @@ -264,4 +268,5 @@ void dcn35_link_encoder_construct( } if (enc10->base.ctx->dc->debug.hdmi20_disable) enc10->base.features.flags.bits.HDMI_6GB_EN = 0; + } -- 2.43.0
[PATCH AUTOSEL 6.7 58/88] drm/amdgpu: fix ftrace event amdgpu_bo_move always move on same heap
From: "Wang, Beyond" [ Upstream commit 94aeb4117343d072e3a35b9595bcbfc0058ee724 ] Issue: during evict or validate happened on amdgpu_bo, the 'from' and 'to' is always same in ftrace event of amdgpu_bo_move where calling the 'trace_amdgpu_bo_move', the comment says move_notify is called before move happens, but actually it is called after move happens, here the new_mem is same as bo->resource Fix: move trace_amdgpu_bo_move from move_notify to amdgpu_bo_move Signed-off-by: Wang, Beyond Reviewed-by: Christian König Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 13 + drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 4 +--- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c| 5 +++-- 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 5ad03f2afdb4..425cebcc5cbf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -1245,19 +1245,15 @@ int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer, * amdgpu_bo_move_notify - notification about a memory move * @bo: pointer to a buffer object * @evict: if this move is evicting the buffer from the graphics address space - * @new_mem: new information of the bufer object * * Marks the corresponding &amdgpu_bo buffer object as invalid, also performs * bookkeeping. * TTM driver callback which is called when ttm moves a buffer. */ -void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, - bool evict, - struct ttm_resource *new_mem) +void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict) { struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); struct amdgpu_bo *abo; - struct ttm_resource *old_mem = bo->resource; if (!amdgpu_bo_is_amdgpu_bo(bo)) return; @@ -1274,13 +1270,6 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, /* remember the eviction */ if (evict) atomic64_inc(&adev->num_evictions); - - /* update statistics */ - if (!new_mem) - return; - - /* move_notify is called before move happens */ - trace_amdgpu_bo_move(abo, new_mem->mem_type, old_mem->mem_type); } void amdgpu_bo_get_memory(struct amdgpu_bo *bo, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h index d28e21baef16..a3ea8a82db23 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h @@ -344,9 +344,7 @@ int amdgpu_bo_set_metadata (struct amdgpu_bo *bo, void *metadata, int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer, size_t buffer_size, uint32_t *metadata_size, uint64_t *flags); -void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, - bool evict, - struct ttm_resource *new_mem); +void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict); void amdgpu_bo_release_notify(struct ttm_buffer_object *bo); vm_fault_t amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo); void amdgpu_bo_fence(struct amdgpu_bo *bo, struct dma_fence *fence, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index ab4a762aed5b..75c9fd2c6c2a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -545,10 +545,11 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict, return r; } + trace_amdgpu_bo_move(abo, new_mem->mem_type, old_mem->mem_type); out: /* update statistics */ atomic64_add(bo->base.size, &adev->num_bytes_moved); - amdgpu_bo_move_notify(bo, evict, new_mem); + amdgpu_bo_move_notify(bo, evict); return 0; } @@ -1553,7 +1554,7 @@ static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo, static void amdgpu_bo_delete_mem_notify(struct ttm_buffer_object *bo) { - amdgpu_bo_move_notify(bo, false, NULL); + amdgpu_bo_move_notify(bo, false); } static struct ttm_device_funcs amdgpu_bo_driver = { -- 2.43.0
[PATCH AUTOSEL 6.7 68/88] drm/amd/display: Fix lightup regression with DP2 single display configs
From: Michael Strauss [ Upstream commit 5a82b8d6c05f9b30828ede1b103b9ee5cb5c912e ] [WHY] Previous fix for multiple displays downstream of DP2 MST hub caused regression [HOW] Match sink IDs instead of sink struct addresses Reviewed-by: Nicholas Kazlauskas Reviewed-by: Charlene Liu Acked-by: Wayne Lin Signed-off-by: Michael Strauss Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c index 2498b8341199..d6a68484153c 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c @@ -157,6 +157,14 @@ bool is_dp2p0_output_encoder(const struct pipe_ctx *pipe_ctx) { /* If this assert is hit then we have a link encoder dynamic management issue */ ASSERT(pipe_ctx->stream_res.hpo_dp_stream_enc ? pipe_ctx->link_res.hpo_dp_link_enc != NULL : true); + /* Count MST hubs once by treating only 1st remote sink in topology as an encoder */ + if (pipe_ctx->stream->link && pipe_ctx->stream->link->remote_sinks[0]) { + return (pipe_ctx->stream_res.hpo_dp_stream_enc && + pipe_ctx->link_res.hpo_dp_link_enc && + dc_is_dp_signal(pipe_ctx->stream->signal) && + (pipe_ctx->stream->link->remote_sinks[0]->sink_id == pipe_ctx->stream->sink->sink_id)); + } + return (pipe_ctx->stream_res.hpo_dp_stream_enc && pipe_ctx->link_res.hpo_dp_link_enc && dc_is_dp_signal(pipe_ctx->stream->signal)); -- 2.43.0
[PATCH AUTOSEL 6.7 64/88] accel/habanalabs: fix EQ heartbeat mechanism
From: Farah Kassabri [ Upstream commit d1958dce5ab6a3e089c60cf474e8c9b7e96e70ad ] Stop rescheduling another heartbeat check when EQ heartbeat check fails as it generates confusing logs in dmesg that the heartbeat fails. Signed-off-by: Farah Kassabri Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay Signed-off-by: Sasha Levin --- drivers/accel/habanalabs/common/device.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/accel/habanalabs/common/device.c b/drivers/accel/habanalabs/common/device.c index 9e461c03e705..9290d4374551 100644 --- a/drivers/accel/habanalabs/common/device.c +++ b/drivers/accel/habanalabs/common/device.c @@ -1044,18 +1044,19 @@ static bool is_pci_link_healthy(struct hl_device *hdev) return (vendor_id == PCI_VENDOR_ID_HABANALABS); } -static void hl_device_eq_heartbeat(struct hl_device *hdev) +static int hl_device_eq_heartbeat_check(struct hl_device *hdev) { - u64 event_mask = HL_NOTIFIER_EVENT_DEVICE_RESET | HL_NOTIFIER_EVENT_DEVICE_UNAVAILABLE; struct asic_fixed_properties *prop = &hdev->asic_prop; if (!prop->cpucp_info.eq_health_check_supported) - return; + return 0; if (hdev->eq_heartbeat_received) hdev->eq_heartbeat_received = false; else - hl_device_cond_reset(hdev, HL_DRV_RESET_HARD, event_mask); + return -EIO; + + return 0; } static void hl_device_heartbeat(struct work_struct *work) @@ -1072,10 +1073,9 @@ static void hl_device_heartbeat(struct work_struct *work) /* * For EQ health check need to check if driver received the heartbeat eq event * in order to validate the eq is working. +* Only if both the EQ is healthy and we managed to send the next heartbeat reschedule. */ - hl_device_eq_heartbeat(hdev); - - if (!hdev->asic_funcs->send_heartbeat(hdev)) + if ((!hl_device_eq_heartbeat_check(hdev)) && (!hdev->asic_funcs->send_heartbeat(hdev))) goto reschedule; if (hl_device_operational(hdev, NULL)) -- 2.43.0
[PATCH AUTOSEL 6.7 65/88] accel/habanalabs/gaudi2: fix undef opcode reporting
From: Dafna Hirschfeld [ Upstream commit 0ec346779644039c4c05cfa7f071b1a24e54d8d9 ] currently the undefined opcode event bit in set only for lower cp and only if 'write_enable' is true. It should be set anyway and for all streams in order to report that event to userspace. Signed-off-by: Dafna Hirschfeld Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay Signed-off-by: Sasha Levin --- drivers/accel/habanalabs/gaudi2/gaudi2.c | 14 ++ 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/accel/habanalabs/gaudi2/gaudi2.c b/drivers/accel/habanalabs/gaudi2/gaudi2.c index 819660c684cf..bc6e338ef2fd 100644 --- a/drivers/accel/habanalabs/gaudi2/gaudi2.c +++ b/drivers/accel/habanalabs/gaudi2/gaudi2.c @@ -7929,21 +7929,19 @@ static int gaudi2_handle_qman_err_generic(struct hl_device *hdev, u16 event_type error_count++; } - if (i == QMAN_STREAMS && error_count) { - /* check for undefined opcode */ - if (glbl_sts_val & PDMA0_QM_GLBL_ERR_STS_CP_UNDEF_CMD_ERR_MASK && - hdev->captured_err_info.undef_opcode.write_enable) { + /* check for undefined opcode */ + if (glbl_sts_val & PDMA0_QM_GLBL_ERR_STS_CP_UNDEF_CMD_ERR_MASK) { + *event_mask |= HL_NOTIFIER_EVENT_UNDEFINED_OPCODE; + if (hdev->captured_err_info.undef_opcode.write_enable) { memset(&hdev->captured_err_info.undef_opcode, 0, sizeof(hdev->captured_err_info.undef_opcode)); - - hdev->captured_err_info.undef_opcode.write_enable = false; hdev->captured_err_info.undef_opcode.timestamp = ktime_get(); hdev->captured_err_info.undef_opcode.engine_id = gaudi2_queue_id_to_engine_id[qid_base]; - *event_mask |= HL_NOTIFIER_EVENT_UNDEFINED_OPCODE; } - handle_lower_qman_data_on_err(hdev, qman_base, *event_mask); + if (i == QMAN_STREAMS) + handle_lower_qman_data_on_err(hdev, qman_base, *event_mask); } } -- 2.43.0
[PATCH AUTOSEL 6.7 66/88] drm/amd/display: make flip_timestamp_in_us a 64-bit variable
From: Josip Pavic [ Upstream commit 6fb12518ca58412dc51054e2a7400afb41328d85 ] [Why] This variable currently overflows after about 71 minutes. This doesn't cause any known functional issues but it does make debugging more difficult. [How] Make it a 64-bit variable. Reviewed-by: Aric Cyr Acked-by: Wayne Lin Signed-off-by: Josip Pavic Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/display/dc/dc_hw_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h index e2a3aa8812df..811474f4419b 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h @@ -244,7 +244,7 @@ enum pixel_format { #define DC_MAX_DIRTY_RECTS 3 struct dc_flip_addrs { struct dc_plane_address address; - unsigned int flip_timestamp_in_us; + unsigned long long flip_timestamp_in_us; bool flip_immediate; /* TODO: add flip duration for FreeSync */ bool triplebuffer_flips; -- 2.43.0
[PATCH AUTOSEL 6.7 75/88] drm/amdgpu: Let KFD sync with VM fences
From: Felix Kuehling [ Upstream commit ec9ba4821fa52b5efdbc4cdf0a77497990655231 ] Change the rules for amdgpu_sync_resv to let KFD synchronize with VM fences on page table reservations. This fixes intermittent memory corruption after evictions when using amdgpu_vm_handle_moved to update page tables for VM mappings managed through render nodes. Signed-off-by: Felix Kuehling Reviewed-by: Christian König Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c index dcd8c066bc1f..1b013a44ca99 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c @@ -191,7 +191,8 @@ static bool amdgpu_sync_test_fence(struct amdgpu_device *adev, /* Never sync to VM updates either. */ if (fence_owner == AMDGPU_FENCE_OWNER_VM && - owner != AMDGPU_FENCE_OWNER_UNDEFINED) + owner != AMDGPU_FENCE_OWNER_UNDEFINED && + owner != AMDGPU_FENCE_OWNER_KFD) return false; /* Ignore fences depending on the sync mode */ -- 2.43.0
[PATCH AUTOSEL 6.7 76/88] drm/amd/display: Fixing stream allocation regression
From: Relja Vojvodic [ Upstream commit 292c2116b2ae84c7e799ae340981e60551b18f5e ] For certain dual display configs that had one display using a 1080p mode, the DPM level used to drive the configs regressed from DPM 0 to DPM 3. This was caused by a missing check that should have only limited the pipe segments on non-phantom pipes. This caused issues with detile buffer allocation, which dissallow subvp from being used Tested-by: Daniel Wheeler Reviewed-by: Dillon Varone Reviewed-by: Martin Leung Acked-by: Rodrigo Siqueira Signed-off-by: Relja Vojvodic Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c index bc5f0db23d0c..a9c45174abed 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c @@ -290,7 +290,7 @@ static void override_det_for_subvp(struct dc *dc, struct dc_state *context, uint for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; - if (pipe_ctx->stream && pipe_ctx->plane_state && pipe_ctx->stream->mall_stream_config.type != SUBVP_PHANTOM) { + if (pipe_ctx->stream && pipe_ctx->plane_state && pipe_ctx->stream->mall_stream_config.type != SUBVP_PHANTOM != SUBVP_PHANTOM) { if (pipe_ctx->stream->timing.v_addressable == 1080 && pipe_ctx->stream->timing.h_addressable == 1920) { if (pipe_segments[i] > 4) pipe_segments[i] = 4; -- 2.43.0
[PATCH AUTOSEL 6.7 74/88] drm/amd/display: Fix minor issues in BW Allocation Phase2
From: Meenakshikumar Somasundaram [ Upstream commit aa5dc05340eb97486a631ce6bccb8d020bf6b56b ] [Why] Fix minor issues in BW Allocation Phase2. [How] - In set_usb4_req_bw_req(), link->dpia_bw_alloc_config.response_ready flag should be reset before writing DPCD REQUEST_BW. - Fix the granularity for value of 2 in get_bw_granularity(). - Removed bandwidth allocation support display fw boot option as the fw would read feature enable status from bios. - Clean up DPIA_EST_BW_CHANGED and DPIA_BW_REQ_SUCCESS cases in dpia_handle_bw_alloc_response(). - Removed allocate_usb4_bw and deallocate_usb4_bw. - Optimized loop in get_lowest_dpia_index(). - Updated link_dp_dpia_allocate_usb4_bandwidth_for_stream() and set_usb4_req_bw_req() to always issue request bw. Tested-by: Daniel Wheeler Reviewed-by: PeiChen Huang Acked-by: Rodrigo Siqueira Signed-off-by: Meenakshikumar Somasundaram Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- .../dc/link/protocols/link_dp_dpia_bw.c | 221 -- .../dc/link/protocols/link_dp_dpia_bw.h | 4 +- 2 files changed, 101 insertions(+), 124 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c index 7581023daa47..d6e1f969bfd5 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c @@ -50,6 +50,7 @@ static bool get_bw_alloc_proceed_flag(struct dc_link *tmp) && tmp->hpd_status && tmp->dpia_bw_alloc_config.bw_alloc_enabled); } + static void reset_bw_alloc_struct(struct dc_link *link) { link->dpia_bw_alloc_config.bw_alloc_enabled = false; @@ -59,6 +60,11 @@ static void reset_bw_alloc_struct(struct dc_link *link) link->dpia_bw_alloc_config.bw_granularity = 0; link->dpia_bw_alloc_config.response_ready = false; } + +#define BW_GRANULARITY_0 4 // 0.25 Gbps +#define BW_GRANULARITY_1 2 // 0.5 Gbps +#define BW_GRANULARITY_2 1 // 1 Gbps + static uint8_t get_bw_granularity(struct dc_link *link) { uint8_t bw_granularity = 0; @@ -71,16 +77,20 @@ static uint8_t get_bw_granularity(struct dc_link *link) switch (bw_granularity & 0x3) { case 0: - bw_granularity = 4; + bw_granularity = BW_GRANULARITY_0; break; case 1: + bw_granularity = BW_GRANULARITY_1; + break; + case 2: default: - bw_granularity = 2; + bw_granularity = BW_GRANULARITY_2; break; } return bw_granularity; } + static int get_estimated_bw(struct dc_link *link) { uint8_t bw_estimated_bw = 0; @@ -93,31 +103,7 @@ static int get_estimated_bw(struct dc_link *link) return bw_estimated_bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); } -static bool allocate_usb4_bw(int *stream_allocated_bw, int bw_needed, struct dc_link *link) -{ - if (bw_needed > 0) - *stream_allocated_bw += bw_needed; - - return true; -} -static bool deallocate_usb4_bw(int *stream_allocated_bw, int bw_to_dealloc, struct dc_link *link) -{ - bool ret = false; - - if (*stream_allocated_bw > 0) { - *stream_allocated_bw -= bw_to_dealloc; - ret = true; - } else { - //Do nothing for now - ret = true; - } - // Unplug so reset values - if (!link->hpd_status) - reset_bw_alloc_struct(link); - - return ret; -} /* * Read all New BW alloc configuration ex: estimated_bw, allocated_bw, * granuality, Driver_ID, CM_Group, & populate the BW allocation structs @@ -128,7 +114,12 @@ static void init_usb4_bw_struct(struct dc_link *link) // Init the known values link->dpia_bw_alloc_config.bw_granularity = get_bw_granularity(link); link->dpia_bw_alloc_config.estimated_bw = get_estimated_bw(link); + + DC_LOG_DEBUG("%s: bw_granularity(%d), estimated_bw(%d)\n", + __func__, link->dpia_bw_alloc_config.bw_granularity, + link->dpia_bw_alloc_config.estimated_bw); } + static uint8_t get_lowest_dpia_index(struct dc_link *link) { const struct dc *dc_struct = link->dc; @@ -141,12 +132,15 @@ static uint8_t get_lowest_dpia_index(struct dc_link *link) dc_struct->links[i]->ep_type != DISPLAY_ENDPOINT_USB4_DPIA) continue; - if (idx > dc_struct->links[i]->link_index) + if (idx > dc_struct->links[i]->link_index) { idx = dc_struct->links[i]->link_index; + break; + } } return idx; } + /* * Get the Max Available BW or Max Estimated BW for each Host Router * @@ -186,6 +180,7 @@ static int get_host_router_total_bw(st
[PATCH AUTOSEL 6.7 69/88] drm/amd/display: Only clear symclk otg flag for HDMI
From: Alvin Lee [ Upstream commit dff45f03f508c92cd8eb2050e27b726726b8ae0b ] [Description] There is a corner case where the symclk otg flag is cleared when disabling the phantom pipe for subvp (because the phantom and main pipe share the same link). This is undesired because we need the maintain the correct symclk otg flag state for the main pipe. For now only clear the flag only for HDMI signal type, since it's only set for HDMI signal type (phantom is virtual). The ideal solution is to not clear it if the stream is phantom but currently there's a bug that doesn't allow us to do this. Once this issue is fixed the proper fix can be implemented. Reviewed-by: Samson Tam Acked-by: Wayne Lin Signed-off-by: Alvin Lee Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c | 3 ++- drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c | 3 ++- drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 3 ++- drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c index 960a55e06375..c0d2e8454efc 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c @@ -2124,7 +2124,8 @@ static void dce110_reset_hw_ctx_wrap( BREAK_TO_DEBUGGER(); } pipe_ctx_old->stream_res.tg->funcs->disable_crtc(pipe_ctx_old->stream_res.tg); - pipe_ctx_old->stream->link->phy_state.symclk_ref_cnts.otg = 0; + if (dc_is_hdmi_tmds_signal(pipe_ctx_old->stream->signal)) + pipe_ctx_old->stream->link->phy_state.symclk_ref_cnts.otg = 0; pipe_ctx_old->plane_res.mi->funcs->free_mem_input( pipe_ctx_old->plane_res.mi, dc->current_state->stream_count); diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c index cdb903116eb7..1fc8436c8130 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c @@ -1057,7 +1057,8 @@ static void dcn10_reset_back_end_for_pipe( if (pipe_ctx->stream_res.tg->funcs->set_drr) pipe_ctx->stream_res.tg->funcs->set_drr( pipe_ctx->stream_res.tg, NULL); - pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg = 0; + if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) + pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg = 0; } for (i = 0; i < dc->res_pool->pipe_count; i++) diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c index c3c83178eb1e..da0181fef411 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c @@ -2610,7 +2610,8 @@ static void dcn20_reset_back_end_for_pipe( * the case where the same symclk is shared across multiple otg * instances */ - link->phy_state.symclk_ref_cnts.otg = 0; + if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) + link->phy_state.symclk_ref_cnts.otg = 0; if (link->phy_state.symclk_state == SYMCLK_ON_TX_OFF) { link_hwss->disable_link_output(link, &pipe_ctx->link_res, pipe_ctx->stream->signal); diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c index 97798cee876e..3a40b7359a30 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c @@ -523,7 +523,8 @@ static void dcn31_reset_back_end_for_pipe( if (pipe_ctx->stream_res.tg->funcs->set_odm_bypass) pipe_ctx->stream_res.tg->funcs->set_odm_bypass( pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing); - pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg = 0; + if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) + pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg = 0; if (pipe_ctx->stream_res.tg->funcs->set_drr) pipe_ctx->stream_res.tg->funcs->set_drr( -- 2.43.0
[PATCH AUTOSEL 6.7 77/88] Re-revert "drm/amd/display: Enable Replay for static screen use cases"
From: Ivan Lipski [ Upstream commit d6398866a6b47e92319ef6efdb0126a4fbb7796a ] This reverts commit 44e60b14d5a72f91fd0bdeae8da59ae37a3ca8e5. Since, it causes a regression in which eDP displays with PSR support, but no Replay support (Sink support <= 0x03), fail to enable PSR and consequently all IGT amd_psr tests fail. So, revert this until a more suitable fix can be found. This got brought back accidently with the backmerge. Acked-by: Leo Li Signed-off-by: Ivan Lipski Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 22 --- .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c| 9 +--- drivers/gpu/drm/amd/include/amd_shared.h | 2 -- 3 files changed, 1 insertion(+), 32 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 4e82ee4d74ac..cf32502d669f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -65,7 +65,6 @@ #include "amdgpu_dm_debugfs.h" #endif #include "amdgpu_dm_psr.h" -#include "amdgpu_dm_replay.h" #include "ivsrcid/ivsrcid_vislands30.h" @@ -4345,7 +4344,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) enum dc_connection_type new_connection_type = dc_connection_none; const struct dc_plane_cap *plane; bool psr_feature_enabled = false; - bool replay_feature_enabled = false; int max_overlay = dm->dc->caps.max_slave_planes; dm->display_indexes_num = dm->dc->caps.max_streams; @@ -4457,20 +4455,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) } } - if (!(amdgpu_dc_debug_mask & DC_DISABLE_REPLAY)) { - switch (adev->ip_versions[DCE_HWIP][0]) { - case IP_VERSION(3, 1, 4): - case IP_VERSION(3, 1, 5): - case IP_VERSION(3, 1, 6): - case IP_VERSION(3, 2, 0): - case IP_VERSION(3, 2, 1): - replay_feature_enabled = true; - break; - default: - replay_feature_enabled = amdgpu_dc_feature_mask & DC_REPLAY_MASK; - break; - } - } /* loops over all connectors on the board */ for (i = 0; i < link_cnt; i++) { struct dc_link *link = NULL; @@ -4519,12 +4503,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) amdgpu_dm_update_connector_after_detect(aconnector); setup_backlight_device(dm, aconnector); - /* -* Disable psr if replay can be enabled -*/ - if (replay_feature_enabled && amdgpu_dm_setup_replay(link, aconnector)) - psr_feature_enabled = false; - if (psr_feature_enabled) amdgpu_dm_set_psr_caps(link); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c index cb0b48bb2a7d..d2834ad85a54 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c @@ -29,7 +29,6 @@ #include "dc.h" #include "amdgpu.h" #include "amdgpu_dm_psr.h" -#include "amdgpu_dm_replay.h" #include "amdgpu_dm_crtc.h" #include "amdgpu_dm_plane.h" #include "amdgpu_dm_trace.h" @@ -124,12 +123,7 @@ static void amdgpu_dm_crtc_vblank_control_worker(struct work_struct *work) * fill_dc_dirty_rects(). */ if (vblank_work->stream && vblank_work->stream->link) { - /* -* Prioritize replay, instead of psr -*/ - if (vblank_work->stream->link->replay_settings.replay_feature_enabled) - amdgpu_dm_replay_enable(vblank_work->stream, false); - else if (vblank_work->enable) { + if (vblank_work->enable) { if (vblank_work->stream->link->psr_settings.psr_version < DC_PSR_VERSION_SU_1 && vblank_work->stream->link->psr_settings.psr_allow_active) amdgpu_dm_psr_disable(vblank_work->stream); @@ -138,7 +132,6 @@ static void amdgpu_dm_crtc_vblank_control_worker(struct work_struct *work) #ifdef CONFIG_DRM_AMD_SECURE_DISPLAY !amdgpu_dm_crc_window_is_activated(&vblank_work->acrtc->base) && #endif - vblank_work->stream->link->panel_config.psr.disallow_replay && vblank_work->acrtc->dm_irq_params.allow_psr_entry) { amdgpu_dm_psr_enable(vblank_work->stream
[PATCH AUTOSEL 6.7 78/88] drm/amdgpu: Fix possible NULL dereference in amdgpu_ras_query_error_status_helper()
From: Srinivasan Shanmugam [ Upstream commit b8d55a90fd55b767c25687747e2b24abd1ef8680 ] Return invalid error code -EINVAL for invalid block id. Fixes the below: drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c:1183 amdgpu_ras_query_error_status_helper() error: we previously assumed 'info' could be null (see line 1176) Suggested-by: Hawking Zhang Cc: Tao Zhou Cc: Hawking Zhang Cc: Christian König Cc: Alex Deucher Signed-off-by: Srinivasan Shanmugam Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index 63fb4cd85e53..4a3726bb6da1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -1174,6 +1174,9 @@ static int amdgpu_ras_query_error_status_helper(struct amdgpu_device *adev, enum amdgpu_ras_block blk = info ? info->head.block : AMDGPU_RAS_BLOCK_COUNT; struct amdgpu_ras_block_object *block_obj = NULL; + if (blk == AMDGPU_RAS_BLOCK_COUNT) + return -EINVAL; + if (error_query_mode == AMDGPU_RAS_INVALID_ERROR_QUERY) return -EINVAL; -- 2.43.0