Re: [RFC PATCH] drm/ssd130x: Allocate buffer in the CRTC's .atomic_check() callback
Hi Javier Am 30.08.23 um 08:25 schrieb Javier Martinez Canillas: The commit 45b58669e532 ("drm/ssd130x: Allocate buffer in the plane's .atomic_check() callback") moved the allocation of the intermediate and HW buffers from the encoder's .atomic_enable callback to primary plane's .atomic_check callback. This was suggested by Maxime Ripard because drivers aren't allowed to fail after drm_atomic_helper_swap_state() has been called, and the encoder's .atomic_enable happens after the new atomic state has been swapped. But that change caused a performance regression in very slow platforms, since now the allocation happens for every plane's atomic state commit. For example, Geert Uytterhoeven reports that is the case on a VexRiscV softcore (RISC-V CPU implementation on an FPGA). To prevent that, move the move the buffers' allocation and free to the Double 'move the' And maybe buffer's rather than buffers' CRTC's .atomic_check and .atomic_destroy_state callbacks, so that only happens on a modeset. Since the intermediate buffer is only needed when not using the controller native format (R1), doing the buffer allocation at that CRTC's .atomic_check time would be enough. Fixes: 45b58669e532 ("drm/ssd130x: Allocate buffer in the plane's .atomic_check() callback") Suggested-by: Geert Uytterhoeven Signed-off-by: Javier Martinez Canillas --- Hello, This is a RFC because I'm not sure if there is a net benefit after this change. I find the currect code much cleaner and less error prone, even when Geert reports that performs worse on his (very slow) platform. But I'm still posting it to see what others think. I've tested the patch on an I2C ssd1306 OLED and found no regressions. The patch is on top on Geert's latest patch-set that adds support for the DRM_FORMAT_R1 to the ssd130x driver: https://lore.kernel.org/dri-devel/cover.1692888745.git.ge...@linux-m68k.org Best regards, Javier drivers/gpu/drm/solomon/ssd130x.c | 106 -- 1 file changed, 56 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index 0d2b36ba4011..60536cd0c42d 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -650,46 +650,6 @@ static int ssd130x_fb_blit_rect(struct drm_plane_state *state, return ret; } -static int ssd130x_primary_plane_helper_atomic_check(struct drm_plane *plane, -struct drm_atomic_state *state) -{ - struct drm_device *drm = plane->dev; - struct ssd130x_device *ssd130x = drm_to_ssd130x(drm); - struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); - struct ssd130x_plane_state *ssd130x_state = to_ssd130x_plane_state(plane_state); - unsigned int page_height = ssd130x->device_info->page_height; - unsigned int pages = DIV_ROUND_UP(ssd130x->height, page_height); - const struct drm_format_info *fi; - unsigned int pitch; - int ret; - - ret = drm_plane_helper_atomic_check(plane, state); - if (ret) - return ret; - - ssd130x_state->data_array = kcalloc(ssd130x->width, pages, GFP_KERNEL); - if (!ssd130x_state->data_array) - return -ENOMEM; - - if (plane_state->fb->format->format != DRM_FORMAT_R1) { - fi = drm_format_info(DRM_FORMAT_R1); - if (!fi) - return -EINVAL; - - pitch = drm_format_info_min_pitch(fi, 0, ssd130x->width); - - ssd130x_state->buffer = kcalloc(pitch, ssd130x->height, GFP_KERNEL); - if (!ssd130x_state->buffer) { - kfree(ssd130x_state->data_array); - /* Set to prevent a double free in .atomic_destroy_state() */ - ssd130x_state->data_array = NULL; - return -ENOMEM; - } - } - - return 0; -} - static void ssd130x_primary_plane_helper_atomic_update(struct drm_plane *plane, struct drm_atomic_state *state) { @@ -762,10 +722,6 @@ static struct drm_plane_state *ssd130x_primary_plane_duplicate_state(struct drm_ if (!ssd130x_state) return NULL; - /* The buffers are not duplicated and are allocated in .atomic_check */ - ssd130x_state->buffer = NULL; - ssd130x_state->data_array = NULL; - new_shadow_plane_state = &ssd130x_state->base; __drm_gem_duplicate_shadow_plane_state(plane, new_shadow_plane_state); @@ -778,9 +734,6 @@ static void ssd130x_primary_plane_destroy_state(struct drm_plane *plane, { struct ssd130x_plane_state *ssd130x_state = to_ssd130x_plane_state(state); - kfree(ssd130x_state->data_array); - kfree(ssd130x_state->buffer); - __drm_gem_destroy_shadow_plane_state(&ssd130x_state->base); kfree(ssd130x_state); @@ -788,7 +7
Re: [PATCH] fbdev: Update fbdev source file paths
Hi Am 29.08.23 um 22:02 schrieb Jonathan Neuschäfer: The files fbmem.c, fb_defio.c, fbsysfs.c, fbmon.c, modedb.c, and fbcmap.c were moved to drivers/video/fbdev, and subsequently to drivers/video/fbdev/core, in the commits listed below. Reported by kalekale in #kernel (Libera IRC). Fixes: f7018c213502 ("video: move fbdev to drivers/video/fbdev") Fixes: 19757fc8432a ("fbdev: move fbdev core files to separate directory") Signed-off-by: Jonathan Neuschäfer IMHO these comments might just be removed. Best regards Thomas --- include/linux/fb.h | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/linux/fb.h b/include/linux/fb.h index ce7d588edc3e6..3cda5b9f2469b 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -592,7 +592,7 @@ extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf, __FB_DEFAULT_SYS_OPS_DRAW, \ __FB_DEFAULT_SYS_OPS_MMAP -/* drivers/video/fbmem.c */ +/* drivers/video/fbdev/core/fbmem.c */ extern int register_framebuffer(struct fb_info *fb_info); extern void unregister_framebuffer(struct fb_info *fb_info); extern int fb_prepare_logo(struct fb_info *fb_info, int rotate); @@ -636,7 +636,7 @@ static inline void __fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, } } -/* drivers/video/fb_defio.c */ +/* drivers/video/fbdev/core/fb_defio.c */ int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma); extern int fb_deferred_io_init(struct fb_info *info); extern void fb_deferred_io_open(struct fb_info *info, @@ -735,14 +735,14 @@ static inline bool fb_be_math(struct fb_info *info) #endif /* CONFIG_FB_FOREIGN_ENDIAN */ } -/* drivers/video/fbsysfs.c */ +/* drivers/video/fbdev/core/fbsysfs.c */ extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev); extern void framebuffer_release(struct fb_info *info); extern int fb_init_device(struct fb_info *fb_info); extern void fb_cleanup_device(struct fb_info *head); extern void fb_bl_default_curve(struct fb_info *fb_info, u8 off, u8 min, u8 max); -/* drivers/video/fbmon.c */ +/* drivers/video/fbdev/core/fbmon.c */ #define FB_MAXTIMINGS 0 #define FB_VSYNCTIMINGS 1 #define FB_HSYNCTIMINGS 2 @@ -776,7 +776,7 @@ extern int of_get_fb_videomode(struct device_node *np, extern int fb_videomode_from_videomode(const struct videomode *vm, struct fb_videomode *fbmode); -/* drivers/video/modedb.c */ +/* drivers/video/fbdev/core/modedb.c */ #define VESA_MODEDB_SIZE 43 #define DMT_SIZE 0x50 @@ -802,7 +802,7 @@ extern void fb_videomode_to_modelist(const struct fb_videomode *modedb, int num, extern const struct fb_videomode *fb_find_best_display(const struct fb_monspecs *specs, struct list_head *head); -/* drivers/video/fbcmap.c */ +/* drivers/video/fbdev/core/fbcmap.c */ extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp); extern int fb_alloc_cmap_gfp(struct fb_cmap *cmap, int len, int transp, gfp_t flags); extern void fb_dealloc_cmap(struct fb_cmap *cmap); -- 2.40.1 -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg) OpenPGP_signature Description: OpenPGP digital signature
Re: [Intel-gfx] [PATCH 0/4] drm/amd/display: stop using drm_edid_override_connector_update()
On Tue, 29 Aug 2023, Alex Hung wrote: > On 2023-08-29 11:03, Jani Nikula wrote: >> On Tue, 29 Aug 2023, Jani Nikula wrote: >>> On Tue, 29 Aug 2023, Alex Deucher wrote: On Tue, Aug 29, 2023 at 6:48 AM Jani Nikula wrote: > > On Wed, 23 Aug 2023, Jani Nikula wrote: >> On Tue, 22 Aug 2023, Alex Hung wrote: >>> On 2023-08-22 06:01, Jani Nikula wrote: Over the past years I've been trying to unify the override and firmware EDID handling as well as EDID property updates. It won't work if drivers do their own random things. >>> Let's check how to replace these references by appropriate ones or fork >>> the function as reverting these patches causes regressions. >> >> I think the fundamental problem you have is conflating connector forcing >> with EDID override. They're orthogonal. The .force callback has no >> business basing the decisions on connector->edid_override. Force is >> force, override is override. >> >> The driver isn't even supposed to know or care if the EDID originates >> from the firmware loader or override EDID debugfs. drm_get_edid() will >> handle that for you transparently. It'll return the EDID, and you >> shouldn't look at connector->edid_blob_ptr either. Using that will make >> future work in drm_edid.c harder. >> >> You can't fix that with minor tweaks. I think you'll be better off >> starting from scratch. >> >> Also, connector->edid_override is debugfs. You actually can change the >> behaviour. If your userspace, whatever it is, has been written to assume >> connector forcing if EDID override is set, you *do* have to fix that, >> and set both. > > Any updates on fixing this, or shall we proceed with the reverts? > > There is a patch under internal reviews. It removes calls edid_override > and drm_edid_override_connector_update as intended in this patchset but > does not remove the functionality. While I am happy to hear there's progress, I'm somewhat baffled the review is internal. The commits that I suggested to revert were also only reviewed internally, as far as I can see... And that's kind of the problem. Upstream code should be reviewed in public. BR, Jani. > > With the patch. both following git grep commands return nothing in > amd-staging-drm-next. > > $ git grep drm_edid_override_connector_update -- drivers/gpu/drm/amd > $ git grep edid_override -- drivers/gpu/drm/amd > > Best regards, > Alex Hung > What is the goal of the reverts? I don't disagree that we may be using the interfaces wrong, but reverting them will regess functionality in the driver. >>> >>> The commits are in v6.5-rc1, but not yet in a release. No user depends >>> on them yet. I'd strongly prefer them not reaching v6.5 final and users. >> >> Sorry for confusion here, that's obviously come and gone already. :( >> >>> The firmware EDID, override EDID, connector forcing, the EDID property, >>> etc. have been and somewhat still are a hairy mess that we must keep >>> untangling, and this isn't helping. >>> >>> I've put in crazy amounts of work on this, and I've added kernel-doc >>> comments about stuff that should and should not be done, but they go >>> unread and ignored. >>> >>> I really don't want to end up having to clean this up myself before I >>> can embark on further cleanups and refactoring. >>> >>> And again, if the functionality in the driver depends on conflating two >>> things that should be separate, it's probably not such a hot idea to let >>> it reach users either. Even if it's just debugfs. >>> >>> >>> BR, >>> Jani. >> -- Jani Nikula, Intel Open Source Graphics Center
[PATCH v1 1/2] dt-bindings: backlight: Add MPS MP3309C
The Monolithic Power (MPS) MP3309C is a WLED step-up converter, featuring a programmable switching frequency to optimize efficiency. The brightness can be controlled either by I2C commands (called "analog" mode) or by a PWM input signal (PWM mode). This driver supports both modes. For device driver details, please refer to: - drivers/video/backlight/mp3309c_bl.c The datasheet is available at: - https://www.monolithicpower.com/en/mp3309c.html Signed-off-by: Flavio Suligoi --- .../bindings/leds/backlight/mps,mp3309c.yaml | 202 ++ 1 file changed, 202 insertions(+) create mode 100644 Documentation/devicetree/bindings/leds/backlight/mps,mp3309c.yaml diff --git a/Documentation/devicetree/bindings/leds/backlight/mps,mp3309c.yaml b/Documentation/devicetree/bindings/leds/backlight/mps,mp3309c.yaml new file mode 100644 index ..a58904f2a271 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/backlight/mps,mp3309c.yaml @@ -0,0 +1,202 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/backlight/mps,mp3309c.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MPS MP3309C backlight + +maintainers: + - Flavio Suligoi + +description: | + The Monolithic Power (MPS) MP3309C is a WLED step-up converter, featuring a + programmable switching frequency to optimize efficiency. + It supports both analog (via I2C commands) and PWM dimming mode. + + The datasheet is available at: + https://www.monolithicpower.com/en/mp3309c.html + +properties: + compatible: +const: mps,mp3309c-backlight + + reg: +maxItems: 1 + + mps,dimming-mode: +description: The dimming mode (PWM or analog by I2C commands). +$ref: '/schemas/types.yaml#/definitions/string' +enum: + - pwm + - analog-i2c + + pinctrl-names: +items: + - const: default + + pinctrl-0: true + + pwms: +description: PWM channel used for controlling the backlight in "pwm" dimming + mode. +maxItems: 1 + + default-brightness: +minimum: 0 + + max-brightness: +minimum: 1 + + enable-gpios: +description: GPIO used to enable the backlight in "analog-i2c" dimming mode. +maxItems: 1 + + mps,switch-on-delay-ms: +description: delay (in ms) before switch on the backlight, to wait for image + stabilization. +default: 10 + + mps,switch-off-delay-ms: +description: delay (in ms) after the switch off command to the backlight. +default: 0 + + mps,overvoltage-protection-13v: +description: overvoltage protection set to 13.5V. +type: boolean + mps,overvoltage-protection-24v: +description: overvoltage protection set to 24V. +type: boolean + mps,overvoltage-protection-35v: +description: overvoltage protection set to 35.5V. +type: boolean + + mps,reset-gpios: +description: optional GPIO to reset an external device (LCD panel, FPGA, + etc.) when the backlight is switched on. +maxItems: 1 + + mps,reset-on-delay-ms: +description: delay (in s) before generating the reset-gpios. +default: 10 + + mps,reset-on-length-ms: +description: pulse length (in ms) for reset-gpios. +default: 10 + +oneOf: + - required: + - mps,overvoltage-protection-13v + - required: + - mps,overvoltage-protection-24v + - required: + - mps,overvoltage-protection-35.5v + +allOf: + - $ref: common.yaml# + - if: + properties: +mps,dimming-mode: + contains: +enum: + - pwm +then: + required: +- pwms + not: +required: + - enable-gpios + + - if: + properties: +mps,dimming-mode: + contains: +enum: + - analog-i2c +then: + required: +- enable-gpios + not: +required: + - pwms + +required: + - compatible + - reg + - mps,dimming-mode + - max-brightness + - default-brightness + +additionalProperties: false + +examples: + - | +#include +i2c3 { +#address-cells = <1>; +#size-cells = <0>; + +clock-frequency = <10>; +pinctrl-names = "default"; +pinctrl-0 = <&pinctrl_i2c3>; +status = "okay"; + +/* Backlight with PWM control */ +backlight_pwm: backlight@17 { +compatible = "mps,mp3309c-backlight"; +reg = <0x17>; +mps,dimming-mode = "pwm"; +pinctrl-names = "default"; +pinctrl-0 = <&pinctrl_fpga_reset>; +pwms = <&pwm1 0 333 0>; /* 300 Hz --> (1/f) * 1*10^9 */ +max-brightness = <100>; +default-brightness = <80>; +mps,switch-on-delay-ms = <800>; +mps,switch-off-delay-ms = <10>; +mps,overvoltage-protection-24v; + +/* + * Enable an FPGA reset pulse when MIPI data are stable, + * before switch on the backlight + */ +mps,rese
[PATCH 1/2] dt-bindings: display/panel: Add AUO G156HAN04.0 LVDS display
From: Elmar Albert Document support for the AUO G156HAN04.0 LVDS display. G156HAN04.0 is a Color Active Matrix Liquid Crystal Display composed of a TFT LCD panel, a driver circuit, and LED backlight system. The screen format is intended to supportthe 16:9 FHD, 1920(H) x 1080(V) screen and 16.7M colors (RGB 8-bits ) with LED backlight driving circuit. All input signals are LVDS interface compatible. G156HAN04.0 is designed for a display unit of notebook style personal computer and industrial machine. Signed-off-by: Elmar Albert --- Cc: Conor Dooley Cc: Daniel Vetter Cc: David Airlie Cc: devicet...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: Krzysztof Kozlowski Cc: Neil Armstrong Cc: Rob Herring Cc: Sam Ravnborg Cc: Thierry Reding --- .../devicetree/bindings/display/panel/panel-simple.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml index 25b4589d4a58..cea702de664b 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml @@ -67,6 +67,8 @@ properties: - auo,g121ean01 # AU Optronics Corporation 13.3" FHD (1920x1080) TFT LCD panel - auo,g133han01 +# AU Optronics Corporation 15.6" FHD (1920x1080) TFT LCD panel + - auo,g156han04 # AU Optronics Corporation 15.6" (1366x768) TFT LCD panel - auo,g156xtn01 # AU Optronics Corporation 18.5" FHD (1920x1080) TFT LCD panel -- 2.34.1
[PATCH v1 2/2] backlight: mp3309c: Add support for MPS MP3309C
The Monolithic Power (MPS) MP3309C is a WLED step-up converter, featuring a programmable switching frequency to optimize efficiency. The brightness can be controlled either by I2C commands (called "analog" mode) or by a PWM input signal (PWM mode). This driver supports both modes. For DT configuration details, please refer to: - Documentation/devicetree/bindings/leds/backlight/mps,mp3309c.yaml The datasheet is available at: - https://www.monolithicpower.com/en/mp3309c.html Signed-off-by: Flavio Suligoi --- MAINTAINERS | 6 + drivers/video/backlight/Kconfig | 13 + drivers/video/backlight/Makefile | 1 + drivers/video/backlight/mp3309c_bl.c | 491 +++ 4 files changed, 511 insertions(+) create mode 100644 drivers/video/backlight/mp3309c_bl.c diff --git a/MAINTAINERS b/MAINTAINERS index 3be1bdfe8ecc..895c56ff4f1e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14333,6 +14333,12 @@ S: Maintained F: Documentation/driver-api/tty/moxa-smartio.rst F: drivers/tty/mxser.* +MP3309C BACKLIGHT DRIVER +M: Flavio Suligoi +S: Maintained +F: Documentation/devicetree/bindings/leds/backlight/mps,mp3309c.yaml +F: drivers/video/backlight/mp3309c_bl.c + MR800 AVERMEDIA USB FM RADIO DRIVER M: Alexey Klimov L: linux-me...@vger.kernel.org diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 51387b1ef012..65d0ac9f611d 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -389,6 +389,19 @@ config BACKLIGHT_LM3639 help This supports TI LM3639 Backlight + 1.5A Flash LED Driver +config BACKLIGHT_MP3309C + tristate "Backlight Driver for MPS MP3309C" + depends on I2C + select REGMAP_I2C + select NEW_LEDS + select LEDS_CLASS + help + This supports MPS MP3309C backlight WLED Driver in both PWM and + analog/I2C dimming modes. + + To compile this driver as a module, choose M here: the module will + be called mp3309c_bl. + config BACKLIGHT_LP855X tristate "Backlight driver for TI LP855X" depends on I2C && PWM diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index f72e1c3c59e9..c42c5bccc5ac 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -44,6 +44,7 @@ obj-$(CONFIG_BACKLIGHT_LP855X)+= lp855x_bl.o obj-$(CONFIG_BACKLIGHT_LP8788) += lp8788_bl.o obj-$(CONFIG_BACKLIGHT_LV5207LP) += lv5207lp.o obj-$(CONFIG_BACKLIGHT_MAX8925)+= max8925_bl.o +obj-$(CONFIG_BACKLIGHT_MP3309C)+= mp3309c_bl.o obj-$(CONFIG_BACKLIGHT_MT6370) += mt6370-backlight.o obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o obj-$(CONFIG_BACKLIGHT_PANDORA)+= pandora_bl.o diff --git a/drivers/video/backlight/mp3309c_bl.c b/drivers/video/backlight/mp3309c_bl.c new file mode 100644 index ..7cb7a542ceca --- /dev/null +++ b/drivers/video/backlight/mp3309c_bl.c @@ -0,0 +1,491 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for MPS MP3309C White LED driver with I2C interface + * + * Copyright (C) 2023 ASEM Srl + * Author: Flavio Suligoi + */ + +#include +#include +#include +#include +#include +#include +#include + +#define REG_I2C_0 0x00 +#define REG_I2C_1 0x01 + +#define REG_I2C_0_EN 0x80 +#define REG_I2C_0_D0 0x40 +#define REG_I2C_0_D1 0x20 +#define REG_I2C_0_D2 0x10 +#define REG_I2C_0_D3 0x08 +#define REG_I2C_0_D4 0x04 +#define REG_I2C_0_RSRV10x02 +#define REG_I2C_0_RSRV20x01 + +#define REG_I2C_1_RSRV10x80 +#define REG_I2C_1_DIMS 0x40 +#define REG_I2C_1_SYNC 0x20 +#define REG_I2C_1_OVP0 0x10 +#define REG_I2C_1_OVP1 0x08 +#define REG_I2C_1_VOS 0x04 +#define REG_I2C_1_LEDO 0x02 +#define REG_I2C_1_OTP 0x01 + +#define ANALOG_MAX_VAL 31 +#define ANALOG_REG_MASK 0x7c + +enum backlight_status { + FIRST_POWER_ON, + BACKLIGHT_OFF, + BACKLIGHT_ON, +}; + +enum dimming_mode_value { + DIMMING_PWM, + DIMMING_ANALOG_I2C, +}; + +struct mp3309c_platform_data { + u32 max_brightness; + u32 brightness; + u32 switch_on_delay_ms; + u32 switch_off_delay_ms; + u32 reset_on_delay_ms; + u32 reset_on_length_ms; + u8 dimming_mode; + u8 reset_pulse_enable; + u8 over_voltage_protection; + + unsigned int status; +}; + +struct mp3309c_chip { + struct device *dev; + struct mp3309c_platform_data *pdata; + struct backlight_device *bl; + struct gpio_desc *enable_gpio; + struct regmap *regmap; + struct pwm_device *pwmd; + + struct delayed_work enable_work; + struct delayed_work reset_gpio_work; + int irq; + + struct gpio_desc *reset_gpio; +}; + +static const struct regmap_config mp3309c_regmap = { + .name = "mp3309c_regmap", + .reg_bits = 8, +
回复: [PATCH] drm/komeda: drop all currently held locks if deadlock happens
Hi Liviu, I have resend that patch and cc to the dri-devel mailing list which public information about it can be looked up now . Please try to deal with this patch when you are available. Best regards, -邮件原件- 发件人: Huang Menghui/黄梦辉 发送时间: 2023年8月4日 10:06 收件人: airl...@gmail.com; dan...@ffwll.ch; dri-devel@lists.freedesktop.org 抄送: liviu.du...@arm.com; Liu Lucas/刘保柱 ; Huang Menghui/黄梦辉 主题: [PATCH] drm/komeda: drop all currently held locks if deadlock happens From: "baozhu.liu" If komeda_pipeline_unbound_components() returns -EDEADLK, it means that a deadlock happened in the locking context. Currently, komeda is not dealing with the deadlock properly,producing the following output when CONFIG_DEBUG_WW_MUTEX_SLOWPATH is enabled: [ cut here ] [ 26.103984] WARNING: CPU: 2 PID: 345 at drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c:1248 komeda_release_unclaimed_resources+0x13c/0x170 [ 26.117453] Modules linked in: [ 26.120511] CPU: 2 PID: 345 Comm: composer@2.1-se Kdump: loaded Tainted: G W 5.10.110-SE-SDK1.8-dirty #16 [ 26.131374] Hardware name: Siengine Se1000 Evaluation board (DT) [ 26.137379] pstate: 2049 (nzCv daif +PAN -UAO -TCO BTYPE=--) [ 26.143385] pc : komeda_release_unclaimed_resources+0x13c/0x170 [ 26.149301] lr : komeda_release_unclaimed_resources+0xbc/0x170 [ 26.155130] sp : 800017b8b8d0 [ 26.158442] pmr_save: 00e0 [ 26.161493] x29: 800017b8b8d0 x28: 000cf2f96200 [ 26.166805] x27: 000c8f5a8800 x26: [ 26.172116] x25: 0038 x24: 8000116a0140 [ 26.177428] x23: 0038 x22: 000cf2f96200 [ 26.182739] x21: 000cfc300300 x20: 000c8ab77080 [ 26.188051] x19: 0003 x18: [ 26.193362] x17: x16: [ 26.198672] x15: b400e638f738ba38 x14: [ 26.203983] x13: 000106400a00 x12: [ 26.209294] x11: x10: [ 26.214604] x9 : 800012f8 x8 : 000ca3308000 [ 26.219915] x7 : 000ff300 x6 : 80001084034c [ 26.225226] x5 : 800017b8bc40 x4 : 000f [ 26.230536] x3 : 000ca3308000 x2 : [ 26.235847] x1 : x0 : ffdd [ 26.241158] Call trace: [ 26.243604] komeda_release_unclaimed_resources+0x13c/0x170 [ 26.249175] komeda_crtc_atomic_check+0x68/0xf0 [ 26.253706] drm_atomic_helper_check_planes+0x138/0x1f4 [ 26.258929] komeda_kms_check+0x284/0x36c [ 26.262939] drm_atomic_check_only+0x40c/0x714 [ 26.267381] drm_atomic_nonblocking_commit+0x1c/0x60 [ 26.272344] drm_mode_atomic_ioctl+0xa3c/0xb8c [ 26.276787] drm_ioctl_kernel+0xc4/0x120 [ 26.280708] drm_ioctl+0x268/0x534 [ 26.284109] __arm64_sys_ioctl+0xa8/0xf0 [ 26.288030] el0_svc_common.constprop.0+0x80/0x240 [ 26.292817] do_el0_svc+0x24/0x90 [ 26.296132] el0_svc+0x20/0x30 [ 26.299185] el0_sync_handler+0xe8/0xf0 [ 26.303018] el0_sync+0x1a4/0x1c0 [ 26.306330] irq event stamp: 0 [ 26.309384] hardirqs last enabled at (0): [<>] 0x0 [ 26.315650] hardirqs last disabled at (0): [] copy_process+0x5d0/0x183c [ 26.323825] softirqs last enabled at (0): [] copy_process+0x5d0/0x183c [ 26.331997] softirqs last disabled at (0): [<>] 0x0 [ 26.338261] ---[ end trace 20ae984fa860184a ]--- [ 26.343021] [ cut here ] [ 26.347646] WARNING: CPU: 3 PID: 345 at drivers/gpu/drm/drm_modeset_lock.c:228 drm_modeset_drop_locks+0x84/0x90 [ 26.357727] Modules linked in: [ 26.360783] CPU: 3 PID: 345 Comm: composer@2.1-se Kdump: loaded Tainted: G W 5.10.110-SE-SDK1.8-dirty #16 [ 26.371645] Hardware name: Siengine Se1000 Evaluation board (DT) [ 26.377647] pstate: 2049 (nzCv daif +PAN -UAO -TCO BTYPE=--) [ 26.383649] pc : drm_modeset_drop_locks+0x84/0x90 [ 26.388351] lr : drm_mode_atomic_ioctl+0x860/0xb8c [ 26.393137] sp : 800017b8bb10 [ 26.396447] pmr_save: 00e0 [ 26.399497] x29: 800017b8bb10 x28: 0001 [ 26.404807] x27: 0038 x26: 0002 [ 26.410115] x25: 000cecbefa00 x24: 000cf2f96200 [ 26.415423] x23: 0001 x22: 0018 [ 26.420731] x21: 0001 x20: 800017b8bc10 [ 26.426039] x19: x18: [ 26.431347] x17: 02e8bf2c x16: 02e94c6b [ 26.436655] x15: 02ea48b9 x14: 8000121f0300 [ 26.441963] x13: 02ee2ca8 x12: 80001129cae0 [ 26.447272] x11: 800012435000 x10: 000ed46b5e88 [ 26.452580] x9 : 000c9935e600 x8 : [ 26.457888] x7 : 8020001e x6 : 8020001f [ 26.463196] x5 : 80001085fbe0 x4 : fe0033a59f20 [ 26.468504] x3 : 8020001e x2 : [ 26.473813] x1 : x0 : 000c8f596090 [ 26.479122] Call trace: [ 26.481566] drm
RE: [PATCH v1 1/2] dt-bindings: backlight: Add MPS MP3309C
Hi Krzysztof, Thanks for your quick replay and corrections! Just some questions about some of your remarks: > > @@ -0,0 +1,202 @@ > > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) %YAML 1.2 > > +--- > > > + > > + reg: > > +maxItems: 1 > > + > > + mps,dimming-mode: > > +description: The dimming mode (PWM or analog by I2C commands). > > +$ref: '/schemas/types.yaml#/definitions/string' > > Drop quotes, you should see warnings for this. > > It does not look like you tested the bindings, at least after quick look. > Please > run `make dt_binding_check` (see > Documentation/devicetree/bindings/writing-schema.rst for instructions). > Maybe you need to update your dtschema and yamllint. > > > +enum: > > + - pwm > > + - analog-i2c > > Why do you think this is a property of a board? Is PWM signal optional? > If so, its presence would define it. Otherwise it seems you want to control > the > driver. > The MP3309C device always need a I2C bus to rd/wr its internal registers. But the brightness can be controlled in one of the following ways (mutually exclusive, but mandatory): - a PWM input signal or - a I2C command So, the driver needs a property to select the dimming mode used; this property is mandatory. This is the reason of the existence of the ' mps,dimming-mode' property. PWM signal is not optional, it is required if and only if the 'pwm' dimming mode is used. If the 'analog-i2c' dimming mode is used, instead, the PWM signal must not be used. So the property 'mps,dimming-mode' controls how the MP3309C is used. I can add more details about this in the description section. ... > > + > > + mps,overvoltage-protection-13v: > > +description: overvoltage protection set to 13.5V. > > +type: boolean > > + mps,overvoltage-protection-24v: > > +description: overvoltage protection set to 24V. > > +type: boolean > > + mps,overvoltage-protection-35v: > > +description: overvoltage protection set to 35.5V. > > +type: boolean > > Nope for these three. Use -microvolt suffix for one property. Ok > > > + > > + mps,reset-gpios: > > +description: optional GPIO to reset an external device (LCD panel, > > FPGA, > > + etc.) when the backlight is switched on. > > +maxItems: 1 > > No, you should not add here GPIOs for other devices. Do you mean that I have to remove this property or that I have to move it somewhere else? I added this feature because sometimes, in embedded boards, you need a pulse signal to use after the backlight probing, for example to reset another device in sync with the backlight probe. Do you think I have to remove this feature from the driver? ... > > +allOf: > > + - $ref: common.yaml# > > + - if: > > + properties: > > +mps,dimming-mode: > > + contains: > > +enum: > > + - pwm > > +then: > > + required: > > +- pwms > > So this proves the point - mps,dimming-mode looks redundant and not > hardware related. See my previous comment. > > > + not: > > +required: > > + - enable-gpios > > + > > + - if: > > + properties: > > +mps,dimming-mode: > > + contains: > > +enum: > > + - analog-i2c > > +then: > > + required: > > +- enable-gpios > > + not: > > +required: > > + - pwms > > + > > +required: > > + - compatible > > + - reg > > + - mps,dimming-mode > > + - max-brightness > > + - default-brightness > > + > > +additionalProperties: false > > Instead: > unevaluatedProperties: false > Ok > > + > > +examples: > > + - | > > +#include > > +i2c3 { > > i2c > > > +#address-cells = <1>; > > +#size-cells = <0>; > > + > > +clock-frequency = <10>; > > Drop > > > +pinctrl-names = "default"; > > +pinctrl-0 = <&pinctrl_i2c3>; > > +status = "okay"; > > Drop all except of cells. Ok > > > + > > +/* Backlight with PWM control */ > > +backlight_pwm: backlight@17 { > > +compatible = "mps,mp3309c-backlight"; > > +reg = <0x17>; > > +mps,dimming-mode = "pwm"; > > +pinctrl-names = "default"; > > +pinctrl-0 = <&pinctrl_fpga_reset>; > > +pwms = <&pwm1 0 333 0>; /* 300 Hz --> (1/f) * 1*10^9 */ > > +max-brightness = <100>; > > +default-brightness = <80>; > > +mps,switch-on-delay-ms = <800>; > > +mps,switch-off-delay-ms = <10>; > > +mps,overvoltage-protection-24v; > > + > > +/* > > + * Enable an FPGA reset pulse when MIPI data are stable, > > + * before switch on the backlight > > + */ > > +mps,reset-gpios = <&gpio4 20 GPIO_ACTIVE_HIGH>; > > Nope, nope. FPGA reset pin is not related to this device. See my previous comment/question about this feature. > > > +mps,reset-on-de
[PATCH] drm/komeda: add NV12 format to support writeback layer type
When testing the d71 writeback layer function, the output format is set to NV12, and the following error message is displayed: [drm:komeda_fb_is_layer_supported] Layer TYPE: 4 doesn't support fb FMT: NV12 little-endian (0x3231564e) with modifier: 0x0.. Check the d71 data manual, writeback layer output formats includes NV12 format. Signed-off-by: baozhu.liu --- drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c index 6c56f5662bc7..80973975bfdb 100644 --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c @@ -521,7 +521,7 @@ static struct komeda_format_caps d71_format_caps_table[] = { {__HW_ID(5, 1), DRM_FORMAT_YUYV,RICH, Rot_ALL_H_V, LYT_NM, AFB_TH}, /* afbc */ {__HW_ID(5, 2), DRM_FORMAT_YUYV,RICH, Flip_H_V, 0, 0}, {__HW_ID(5, 3), DRM_FORMAT_UYVY,RICH, Flip_H_V, 0, 0}, - {__HW_ID(5, 6), DRM_FORMAT_NV12,RICH, Flip_H_V, 0, 0}, + {__HW_ID(5, 6), DRM_FORMAT_NV12,RICH_WB,Flip_H_V, 0, 0}, {__HW_ID(5, 6), DRM_FORMAT_YUV420_8BIT, RICH, Rot_ALL_H_V, LYT_NM, AFB_TH}, /* afbc */ {__HW_ID(5, 7), DRM_FORMAT_YUV420, RICH, Flip_H_V, 0, 0}, /* YUV 10bit*/ -- 2.17.1
[PATCH 2/2] drm/panel: Add AUO G156HAN04.0 LVDS display support
From: Elmar Albert G156HAN04.0 is a Color Active Matrix Liquid Crystal Display composed of a TFT LCD panel, a driver circuit, and LED backlight system. The screen format is intended to supportthe 16:9 FHD, 1920(H) x 1080(V) screen and 16.7M colors (RGB 8-bits ) with LED backlight driving circuit. All input signals are LVDS interface compatible. G156HAN04.0 is designed for a display unit of notebook style personal computer and industrial machine. Signed-off-by: Elmar Albert --- Cc: Conor Dooley Cc: Daniel Vetter Cc: David Airlie Cc: devicet...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: Krzysztof Kozlowski Cc: Neil Armstrong Cc: Rob Herring Cc: Sam Ravnborg Cc: Thierry Reding --- drivers/gpu/drm/panel/panel-simple.c | 36 1 file changed, 36 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 52572fde9705..4fe6dafcabf6 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -1050,6 +1050,39 @@ static const struct panel_desc auo_g133han01 = { .connector_type = DRM_MODE_CONNECTOR_LVDS, }; +static const struct display_timing auo_g156han04_timings = { + .pixelclock = { 13700, 14100, 14600 }, + + .hactive = { 1920, 1920, 1920 }, + .hfront_porch = { 60, 60, 60 }, + .hback_porch = { 90, 92, 111 }, + .hsync_len ={ 32, 32, 32 }, + + .vactive = { 1080, 1080, 1080 }, + .vfront_porch = { 12, 12, 12 }, + .vback_porch = { 24, 36, 56 }, + .vsync_len ={ 8, 8, 8 }, +}; + +static const struct panel_desc auo_g156han04 = { + .timings = &auo_g156han04_timings, + .num_timings = 1, + .bpc = 8, + .size = { + .width = 344, + .height = 194, + }, + .delay = { + .prepare = 50, /* T2 */ + .enable = 200, /* T3 */ + .disable = 110, /* T10 */ + .unprepare = 1000, /* T13 */ + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .bus_flags = DRM_BUS_FLAG_DE_HIGH, + .connector_type = DRM_MODE_CONNECTOR_LVDS, +}; + static const struct drm_display_mode auo_g156xtn01_mode = { .clock = 76000, .hdisplay = 1366, @@ -4118,6 +4151,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "auo,g133han01", .data = &auo_g133han01, + }, { + .compatible = "auo,g156han04", + .data = &auo_g156han04, }, { .compatible = "auo,g156xtn01", .data = &auo_g156xtn01, -- 2.34.1
Re: [PATCH drm-misc-next 2/3] drm/gpuva_mgr: generalize dma_resv/extobj handling and GEM validation
Hi, Danilo. Some quick comments since I'm doing some Xe work in this area. Will probably get back with more. On 8/20/23 23:53, Danilo Krummrich wrote: So far the DRM GPUVA manager offers common infrastructure to track GPU VA allocations and mappings, generically connect GPU VA mappings to their backing buffers and perform more complex mapping operations on the GPU VA space. However, there are more design patterns commonly used by drivers, which can potentially be generalized in order to make the DRM GPUVA manager represent a basic GPU-VM implementation. In this context, this patch aims at generalizing the following elements. 1) Provide a common dma-resv for GEM objects not being used outside of this GPU-VM. 2) Provide tracking of external GEM objects (GEM objects which are shared with other GPU-VMs). 3) Provide functions to efficiently lock all GEM objects dma-resv the GPU-VM contains mappings of. 4) Provide tracking of evicted GEM objects the GPU-VM contains mappings of, such that validation of evicted GEM objects is accelerated. 5) Provide some convinience functions for common patterns. Rather than being designed as a "framework", the target is to make all features appear as a collection of optional helper functions, such that drivers are free to make use of the DRM GPUVA managers basic functionality and opt-in for other features without setting any feature flags, just by making use of the corresponding functions. Signed-off-by: Danilo Krummrich --- drivers/gpu/drm/drm_gpuva_mgr.c | 688 +++- include/drm/drm_gem.h | 48 ++- include/drm/drm_gpuva_mgr.h | 302 +- 3 files changed, 1010 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/drm_gpuva_mgr.c b/drivers/gpu/drm/drm_gpuva_mgr.c index f86bfad74ff8..69872b205961 100644 --- a/drivers/gpu/drm/drm_gpuva_mgr.c +++ b/drivers/gpu/drm/drm_gpuva_mgr.c @@ -655,6 +655,7 @@ drm_gpuva_range_valid(struct drm_gpuva_manager *mgr, /** * drm_gpuva_manager_init() - initialize a &drm_gpuva_manager * @mgr: pointer to the &drm_gpuva_manager to initialize + * @drm: the drivers &drm_device * @name: the name of the GPU VA space * @start_offset: the start offset of the GPU VA space * @range: the size of the GPU VA space @@ -669,6 +670,7 @@ drm_gpuva_range_valid(struct drm_gpuva_manager *mgr, */ void drm_gpuva_manager_init(struct drm_gpuva_manager *mgr, + struct drm_device *drm, const char *name, u64 start_offset, u64 range, u64 reserve_offset, u64 reserve_range, @@ -677,6 +679,11 @@ drm_gpuva_manager_init(struct drm_gpuva_manager *mgr, mgr->rb.tree = RB_ROOT_CACHED; INIT_LIST_HEAD(&mgr->rb.list); + mt_init(&mgr->mt_ext); + + INIT_LIST_HEAD(&mgr->evict.list); + spin_lock_init(&mgr->evict.lock); + drm_gpuva_check_overflow(start_offset, range); mgr->mm_start = start_offset; mgr->mm_range = range; @@ -694,6 +701,9 @@ drm_gpuva_manager_init(struct drm_gpuva_manager *mgr, reserve_range))) __drm_gpuva_insert(mgr, &mgr->kernel_alloc_node); } + + drm_gem_private_object_init(drm, &mgr->d_obj, 0); + mgr->resv = mgr->d_obj.resv; } EXPORT_SYMBOL_GPL(drm_gpuva_manager_init); @@ -713,10 +723,575 @@ drm_gpuva_manager_destroy(struct drm_gpuva_manager *mgr) __drm_gpuva_remove(&mgr->kernel_alloc_node); WARN(!RB_EMPTY_ROOT(&mgr->rb.tree.rb_root), -"GPUVA tree is not empty, potentially leaking memory."); +"GPUVA tree is not empty, potentially leaking memory.\n"); + + mtree_destroy(&mgr->mt_ext); + WARN(!list_empty(&mgr->evict.list), "Evict list should be empty.\n"); + + drm_gem_private_object_fini(&mgr->d_obj); } EXPORT_SYMBOL_GPL(drm_gpuva_manager_destroy); +/** + * drm_gpuva_manager_prepare_objects() - prepare all assoiciated BOs + * @mgr: the &drm_gpuva_manager + * @num_fences: the amount of &dma_fences to reserve + * + * Calls drm_exec_prepare_obj() for all &drm_gem_objects the given + * &drm_gpuva_manager contains mappings of. + * + * Drivers can obtain the corresponding &drm_exec instance through + * DRM_GPUVA_EXEC(). It is the drivers responsibility to call drm_exec_init() + * and drm_exec_fini() accordingly. + * + * Returns: 0 on success, negative error code on failure. + */ +int +drm_gpuva_manager_prepare_objects(struct drm_gpuva_manager *mgr, + unsigned int num_fences) +{ + struct drm_exec *exec = DRM_GPUVA_EXEC(mgr); + MA_STATE(mas, &mgr->mt_ext, 0, 0); + union { + void *ptr; + uintptr_t cnt; + } ref; + int ret; + + ret = drm_exec_prepare_obj(exec, &mgr->d_obj, num_fences); + if (ret) + goto out; + + rcu_read_lock(); In xe we'
Re: [RFC PATCH] drm/ssd130x: Allocate buffer in the CRTC's .atomic_check() callback
Hi Thomas, On Wed, Aug 30, 2023 at 9:08 AM Thomas Zimmermann wrote: > Am 30.08.23 um 08:25 schrieb Javier Martinez Canillas: > > The commit 45b58669e532 ("drm/ssd130x: Allocate buffer in the plane's > > .atomic_check() callback") moved the allocation of the intermediate and > > HW buffers from the encoder's .atomic_enable callback to primary plane's > > .atomic_check callback. > > > > This was suggested by Maxime Ripard because drivers aren't allowed to fail > > after drm_atomic_helper_swap_state() has been called, and the encoder's > > .atomic_enable happens after the new atomic state has been swapped. > > > > But that change caused a performance regression in very slow platforms, > > since now the allocation happens for every plane's atomic state commit. > > For example, Geert Uytterhoeven reports that is the case on a VexRiscV > > softcore (RISC-V CPU implementation on an FPGA). > > > > To prevent that, move the move the buffers' allocation and free to the > > Double 'move the' > > And maybe buffer's rather than buffers' > > > CRTC's .atomic_check and .atomic_destroy_state callbacks, so that only > > happens on a modeset. Since the intermediate buffer is only needed when > > not using the controller native format (R1), doing the buffer allocation > > at that CRTC's .atomic_check time would be enough. > > > > Fixes: 45b58669e532 ("drm/ssd130x: Allocate buffer in the plane's > > .atomic_check() callback") > > Suggested-by: Geert Uytterhoeven > > Signed-off-by: Javier Martinez Canillas Javier: thanks for your patch! > Besides the pointers, the CRTC state can also store the primary plane > format, which you update from the plane's atomic check. By doing so, you > wont need to refer to the plane state from the CRTC's atomic_check. The > plane's atomic_check runs before the CRTC's atomic_check. [1] I haven't tested Javier's patch yet, but does this mean that his patch won't help? The problem I saw was that these buffers were allocated and freed over and over again on each flash of the cursor of the text console on top of the emulated frame buffer device. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [RFC PATCH] drm/ssd130x: Allocate buffer in the CRTC's .atomic_check() callback
Hi Geert Am 30.08.23 um 09:40 schrieb Geert Uytterhoeven: Hi Thomas, On Wed, Aug 30, 2023 at 9:08 AM Thomas Zimmermann wrote: Am 30.08.23 um 08:25 schrieb Javier Martinez Canillas: The commit 45b58669e532 ("drm/ssd130x: Allocate buffer in the plane's .atomic_check() callback") moved the allocation of the intermediate and HW buffers from the encoder's .atomic_enable callback to primary plane's .atomic_check callback. This was suggested by Maxime Ripard because drivers aren't allowed to fail after drm_atomic_helper_swap_state() has been called, and the encoder's .atomic_enable happens after the new atomic state has been swapped. But that change caused a performance regression in very slow platforms, since now the allocation happens for every plane's atomic state commit. For example, Geert Uytterhoeven reports that is the case on a VexRiscV softcore (RISC-V CPU implementation on an FPGA). To prevent that, move the move the buffers' allocation and free to the Double 'move the' And maybe buffer's rather than buffers' Scratch that remark. CRTC's .atomic_check and .atomic_destroy_state callbacks, so that only happens on a modeset. Since the intermediate buffer is only needed when not using the controller native format (R1), doing the buffer allocation at that CRTC's .atomic_check time would be enough. Fixes: 45b58669e532 ("drm/ssd130x: Allocate buffer in the plane's .atomic_check() callback") Suggested-by: Geert Uytterhoeven Signed-off-by: Javier Martinez Canillas Javier: thanks for your patch! Besides the pointers, the CRTC state can also store the primary plane format, which you update from the plane's atomic check. By doing so, you wont need to refer to the plane state from the CRTC's atomic_check. The plane's atomic_check runs before the CRTC's atomic_check. [1] I haven't tested Javier's patch yet, but does this mean that his patch won't help? The problem I saw was that these buffers were allocated and freed over and over again on each flash of the cursor of the text console on top of the emulated frame buffer device. Javier's current patch should resolve this problem. The temporary buffers are now only allocated on display-mode/format changes, but not on each single screen update. My review concerns only the implementation. Best regards Thomas Gr{oetje,eeting}s, Geert -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg) OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH drm-misc-next 2/3] drm/gpuva_mgr: generalize dma_resv/extobj handling and GEM validation
Am 20.08.23 um 23:53 schrieb Danilo Krummrich: So far the DRM GPUVA manager offers common infrastructure to track GPU VA allocations and mappings, generically connect GPU VA mappings to their backing buffers and perform more complex mapping operations on the GPU VA space. However, there are more design patterns commonly used by drivers, which can potentially be generalized in order to make the DRM GPUVA manager represent a basic GPU-VM implementation. In this context, this patch aims at generalizing the following elements. 1) Provide a common dma-resv for GEM objects not being used outside of this GPU-VM. 2) Provide tracking of external GEM objects (GEM objects which are shared with other GPU-VMs). 3) Provide functions to efficiently lock all GEM objects dma-resv the GPU-VM contains mappings of. 4) Provide tracking of evicted GEM objects the GPU-VM contains mappings of, such that validation of evicted GEM objects is accelerated. 5) Provide some convinience functions for common patterns. Interesting work. You basically implement a bunch of the ideas I came up to improve the amdgpu performance in the common manager now. The was one of the remaining blockers I had for using this in amdgpu. Question is for example how do you track evictions? E.g. we don't have a common concept of eviction in GEM as far as I know. Or is the driver responsible for giving those notifications to the GPUVA manager? And would it be possible to lock only a specific area of the VM, e.g. every BO mapped in the interval X..Y? Regards, Christian. Rather than being designed as a "framework", the target is to make all features appear as a collection of optional helper functions, such that drivers are free to make use of the DRM GPUVA managers basic functionality and opt-in for other features without setting any feature flags, just by making use of the corresponding functions. Signed-off-by: Danilo Krummrich --- drivers/gpu/drm/drm_gpuva_mgr.c | 688 +++- include/drm/drm_gem.h | 48 ++- include/drm/drm_gpuva_mgr.h | 302 +- 3 files changed, 1010 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/drm_gpuva_mgr.c b/drivers/gpu/drm/drm_gpuva_mgr.c index f86bfad74ff8..69872b205961 100644 --- a/drivers/gpu/drm/drm_gpuva_mgr.c +++ b/drivers/gpu/drm/drm_gpuva_mgr.c @@ -655,6 +655,7 @@ drm_gpuva_range_valid(struct drm_gpuva_manager *mgr, /** * drm_gpuva_manager_init() - initialize a &drm_gpuva_manager * @mgr: pointer to the &drm_gpuva_manager to initialize + * @drm: the drivers &drm_device * @name: the name of the GPU VA space * @start_offset: the start offset of the GPU VA space * @range: the size of the GPU VA space @@ -669,6 +670,7 @@ drm_gpuva_range_valid(struct drm_gpuva_manager *mgr, */ void drm_gpuva_manager_init(struct drm_gpuva_manager *mgr, + struct drm_device *drm, const char *name, u64 start_offset, u64 range, u64 reserve_offset, u64 reserve_range, @@ -677,6 +679,11 @@ drm_gpuva_manager_init(struct drm_gpuva_manager *mgr, mgr->rb.tree = RB_ROOT_CACHED; INIT_LIST_HEAD(&mgr->rb.list); + mt_init(&mgr->mt_ext); + + INIT_LIST_HEAD(&mgr->evict.list); + spin_lock_init(&mgr->evict.lock); + drm_gpuva_check_overflow(start_offset, range); mgr->mm_start = start_offset; mgr->mm_range = range; @@ -694,6 +701,9 @@ drm_gpuva_manager_init(struct drm_gpuva_manager *mgr, reserve_range))) __drm_gpuva_insert(mgr, &mgr->kernel_alloc_node); } + + drm_gem_private_object_init(drm, &mgr->d_obj, 0); + mgr->resv = mgr->d_obj.resv; } EXPORT_SYMBOL_GPL(drm_gpuva_manager_init); @@ -713,10 +723,575 @@ drm_gpuva_manager_destroy(struct drm_gpuva_manager *mgr) __drm_gpuva_remove(&mgr->kernel_alloc_node); WARN(!RB_EMPTY_ROOT(&mgr->rb.tree.rb_root), -"GPUVA tree is not empty, potentially leaking memory."); +"GPUVA tree is not empty, potentially leaking memory.\n"); + + mtree_destroy(&mgr->mt_ext); + WARN(!list_empty(&mgr->evict.list), "Evict list should be empty.\n"); + + drm_gem_private_object_fini(&mgr->d_obj); } EXPORT_SYMBOL_GPL(drm_gpuva_manager_destroy); +/** + * drm_gpuva_manager_prepare_objects() - prepare all assoiciated BOs + * @mgr: the &drm_gpuva_manager + * @num_fences: the amount of &dma_fences to reserve + * + * Calls drm_exec_prepare_obj() for all &drm_gem_objects the given + * &drm_gpuva_manager contains mappings of. + * + * Drivers can obtain the corresponding &drm_exec instance through + * DRM_GPUVA_EXEC(). It is the drivers responsibility to call drm_exec_init() + * and drm_exec_fini() accordingly. + * + * Returns: 0 on success, negative error code on failure. + */ +int +drm_gpuva_manager_prepare_o
Re: [1/2] drm/display/dp: Assume 8 bpc support when DSC is supported
On Thu, Aug 24, 2023 at 06:21:20PM +0530, Ankit Nautiyal wrote: > As per DP v1.4, a DP DSC Sink device shall support 8bpc in DPCD 6Ah. > Apparently some panels that do support DSC, are not setting the bit for > 8bpc. > > So always assume 8bpc support by DSC decoder, when DSC is claimed to be > supported. > > v2: Use helper to get check dsc support. (Ankit) > v3: Fix styling and other typos. (Jani) > > Signed-off-by: Ankit Nautiyal Reviewed-by: Stanislav Lisovskiy > --- > drivers/gpu/drm/display/drm_dp_helper.c | 8 ++-- > 1 file changed, 6 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/display/drm_dp_helper.c > b/drivers/gpu/drm/display/drm_dp_helper.c > index e6a78fd32380..8a1b64c57dfd 100644 > --- a/drivers/gpu/drm/display/drm_dp_helper.c > +++ b/drivers/gpu/drm/display/drm_dp_helper.c > @@ -2449,12 +2449,16 @@ int drm_dp_dsc_sink_supported_input_bpcs(const u8 > dsc_dpcd[DP_DSC_RECEIVER_CAP_S > int num_bpc = 0; > u8 color_depth = dsc_dpcd[DP_DSC_DEC_COLOR_DEPTH_CAP - DP_DSC_SUPPORT]; > > + if (!drm_dp_sink_supports_dsc(dsc_dpcd)) > + return 0; > + > if (color_depth & DP_DSC_12_BPC) > dsc_bpc[num_bpc++] = 12; > if (color_depth & DP_DSC_10_BPC) > dsc_bpc[num_bpc++] = 10; > - if (color_depth & DP_DSC_8_BPC) > - dsc_bpc[num_bpc++] = 8; > + > + /* A DP DSC Sink device shall support 8 bpc. */ > + dsc_bpc[num_bpc++] = 8; > > return num_bpc; > }
Re: [PATCH 2/5] drm/debugfs: disallow debugfs access when device isn't registered
Am 29.08.23 um 14:31 schrieb Christian König: Am 29.08.23 um 13:38 schrieb Andi Shyti: During device bringup it might be that we can't access the debugfs files. Return -ENODEV until the registration is completed on access. just wondering, if the device is not registered, how do we get there? The workflow is: 1. Creation (DRM) 2. Initialization (Driver) 3. Registration (DRM) ... 4. Unregistration (DRM) 5. Deinitialization (Driver) 6. Destruction (DRM) It is possible that debugfs files are created during driver initialization, but Daniel insisted that they should not be accessible until the registration is done (which makes the other UAPI accessible as well). makes sense, but then why not -EAGAIN, or -EBUSY? Good question. I think the main use case for this is between 4 and 6. E.g. a device which is hot removed and now in the process of being torn down. In this situation we might still have references from userspace (memory mapping etc...), so the drm file and with it the debugfs directory is still there but the physical device is gone. For the IOCTL UAPI we then also return -ENODEV as well, so this makes sense. The time between 1 and 3 is interesting as well, but here it's more like we couldn't get the device initialized and are now stuck. This happens sometimes during early hardware bringup and I still disagree with Daniel that we should block that (well on the other hand it's trivial for a developer to comment those checks out). Could I get an rb for this series or at least this patch from you? I would really like to push that now as long as neither Dave nor Daniel have any objections (last time I checked the Intel CI was happy as well, but we could re-submit that once more of course). Thanks, Christian. Regards, Christian. Thanks, Andi
Re: [PATCH 1/5] drm/debugfs: drop debugfs_init() for the render and accel node v2
Hi Christian, On Tue, Aug 29, 2023 at 01:01:11PM +0200, Christian König wrote: > We want to remove per minor debugfs directories. Start by stopping > drivers from adding anything inside of those in the mid layer callback. > > v2: drop it for the accel node as well > > Signed-off-by: Christian König > Tested-by: Stanislaw Gruszka Reviewed-by: Andi Shyti Thanks, Andi
Re: [PATCH 5/7] drm: adv7511: Add has_dsi feature bit to struct adv7511_chip_info
On Tue, Aug 29, 2023 at 03:42:40PM +, Biju Das wrote: > Hi Laurent Pinchart, > > Thanks for the feedback. > > > Subject: Re: [PATCH 5/7] drm: adv7511: Add has_dsi feature bit to struct > > adv7511_chip_info > > > > Hi Biju, > > > > On Tue, Aug 29, 2023 at 02:19:02PM +, Biju Das wrote: > > > Subject: Re: [PATCH 5/7] drm: adv7511: Add has_dsi feature bit to > > > struct adv7511_chip_info > > > > On Sun, Aug 13, 2023 at 07:05:10PM +0100, Biju Das wrote: > > > > > The ADV7533 and ADV7535 have DSI support. Add a feature bit > > > > > has_dsi to struct adv7511_chip_info for handling configuration > > related to DSI. > > > > > > > > > > Signed-off-by: Biju Das > > > > > --- > > > > > drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 + > > > > > drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 20 > > > > > +++- > > > > > 2 files changed, 12 insertions(+), 9 deletions(-) > > > > > > > > > > diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h > > > > > b/drivers/gpu/drm/bridge/adv7511/adv7511.h > > > > > index b29d11cae932..2a017bb31a14 100644 > > > > > --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h > > > > > +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h > > > > > @@ -339,6 +339,7 @@ struct adv7511_chip_info { > > > > > unsigned long max_lane_freq; > > > > > const char * const *supply_names; > > > > > unsigned int num_supplies; > > > > > + unsigned has_dsi:1; > > > > > > > > As you're not short of space here, I'd make this a bool. > > > > > > OK, will use bool here. > > > > > > > > }; > > > > > > > > > > struct adv7511 { > > > > > diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c > > > > > b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c > > > > > index f6f15c1b0882..66b3f8fcf67d 100644 > > > > > --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c > > > > > +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c > > > > > @@ -373,7 +373,7 @@ static void adv7511_power_on(struct adv7511 > > *adv7511) > > > > >*/ > > > > > regcache_sync(adv7511->regmap); > > > > > > > > > > - if (adv7511->info->type == ADV7533 || adv7511->info->type == > > ADV7535) > > > > > + if (adv7511->info->has_dsi) > > > > > adv7533_dsi_power_on(adv7511); > > > > > adv7511->powered = true; > > > > > } > > > > > @@ -397,7 +397,7 @@ static void __adv7511_power_off(struct adv7511 > > > > > *adv7511) static void adv7511_power_off(struct adv7511 *adv7511) { > > > > > __adv7511_power_off(adv7511); > > > > > - if (adv7511->info->type == ADV7533 || adv7511->info->type == > > ADV7535) > > > > > + if (adv7511->info->has_dsi) > > > > > adv7533_dsi_power_off(adv7511); > > > > > adv7511->powered = false; > > > > > } > > > > > @@ -786,7 +786,7 @@ static void adv7511_mode_set(struct adv7511 > > *adv7511, > > > > > else > > > > > low_refresh_rate = ADV7511_LOW_REFRESH_RATE_NONE; > > > > > > > > > > - if (adv7511->info->type == ADV7511) > > > > > + if (!adv7511->info->has_dsi) > > > > > > > > While this is functionally equivalent, is the register below really > > > > related to DSI ? If not, I'd rather not check the has_dsi field here > > > > but keep checking the type. > > > > > > What creating a packed value for this hardware difference as driver > > > data? > > > > > > { 0xfb, 0x6, 0x1} and { 0x4a, 0xc, 2) packed as unsigned int driver > > > data low_refresh_data and we can get rid of this if statement and > > > depack it here. > > > > As we're not in a hot path, I think the most important criteria to consider > > are maintainability and readability. Making it easy to add support for a > > new chip without creating a mess of spaghetti code falls into those > > criteria, but as far as I'm aware there's no indication that we will > > suddenly see several new compatible devices. > > > > When it comes to readability, code such as > > > > if (has_dsi) > > init_dsi(); > > > > is great, but code such as > > > > if (has_dsi) > > init_cec(); > > > > because only the DSI-enabled version happens to also support CEC is not > > good. Similarly, I don't think packing the refresh rate register addresses > > and value in the info structure would increase readability, or help in any > > real way. I'm tempted to leave it as-is. > > Agreed. Will keep as it is for low_refresh_rate() change. > > > > > What would help readability, if you feel inclined to keep working on this > > driver, is to replace the register addresses with named macros :-) > > > > > > > regmap_update_bits(adv7511->regmap, 0xfb, > > > > > 0x6, low_refresh_rate << 1); > > > > > else > > > > > @@ -921,7 +921,7 @@ static enum drm_mode_status > > > > > adv7511_bridge_mode_valid(struct drm_bridge *bridge, { > > > > > struct adv7511 *adv = bridge_to_adv7511(bridge); > > > > > > > > > > - if (adv->info->type == ADV7533 || adv->info->type == ADV7535) >
RE: [RFC 00/33] Add Support for Plane Color Pipeline
> -Original Message- > From: Harry Wentland > Sent: Wednesday, August 30, 2023 12:56 AM > To: Shankar, Uma ; intel-...@lists.freedesktop.org; > dri- > de...@lists.freedesktop.org > Cc: wayland-de...@lists.freedesktop.org; Ville Syrjala > ; Pekka Paalanen > ; > Simon Ser ; Melissa Wen ; Jonas Ådahl > ; Sebastian Wick ; Shashank > Sharma ; Alexander Goins ; > Naseer Ahmed ; Christopher Braga > > Subject: Re: [RFC 00/33] Add Support for Plane Color Pipeline > > +CC Naseer and Chris, FYI > > See https://patchwork.freedesktop.org/series/123024/ for whole series. > > On 2023-08-29 12:03, Uma Shankar wrote: > > Introduction > > > > > > Modern hardwares have various color processing capabilities both at > > pre-blending and post-blending phases in the color pipeline. > > The current drm implementation exposes only the post-blending color > > hardware blocks. Support for pre-blending hardware is missing. > > There are multiple use cases where pre-blending color hardware will be > > useful: > > a) Linearization of input buffers encoded in various transfer > >functions. > > b) Color Space conversion > > c) Tone mapping > > d) Frame buffer format conversion > > e) Non-linearization of buffer(apply transfer function) > > f) 3D Luts > > > > and other miscellaneous color operations. > > > > Hence, there is a need to expose the color capabilities of the > > hardware to user-space. This will help userspace/middleware to use > > display hardware for color processing and blending instead of doing it > > through GPU shaders. > > > > Thanks, Uma, for sending this. I've been working on something similar but you > beat > me to it. :) Thanks Harry for the useful feedback and overall collaboration on this so far. > > > > Work done so far and relevant references > > > > > > Some implementation is done by Intel and AMD/Igalia to address the same. > > Broad consensus is there that we need a generic API at drm core to > > suffice the use case of various HW vendors. Below are the links > > capturing the discussion so far. > > > > Intel's Plane Color Implementation: > > https://patchwork.freedesktop.org/series/90825/ > > AMD's Plane Color Implementation: > > https://patchwork.freedesktop.org/series/116862/ > > > > > > Hackfest conclusions > > > > > > HDR/Color Hackfest was organised by Redhat to bring all the industry > > stakeholders together and converge on a common uapi expectations. > > Participants from Intel, AMD, Nvidia, Collabora, Redhat, Igalia and > > other prominent user-space developers and maintainers. > > > > Discussions happened on the uapi expectations, opens, nature of > > hardware of multiple hardware vendors, challenges in generalizing the > > same and the path forward. Consensus was made that drm core should > > implement descriptive APIs and not go with prescriptive APIs. DRM core > > should just expose the hardware capabilities; enabling, customizing > > and programming the same should be done by the user-space. Driver should > > just > honor the user space request without doing any operations internally. > > > > Thanks to Simon Ser, for nicely documenting the design consensus and > > an UAPI RFC which can be referred to here: > > > > https://lore.kernel.org/dri-devel/QMers3awXvNCQlyhWdTtsPwkp5ie9bze_hD5 > > > nAccFW7a_RXlWjYB7MoUW_8CKLT2bSQwIXVi5H6VULYIxCdgvryZoAoJnC5lZgyK1Q > Wn48 > > 8=@emersion.fr/ > > > > > > Design considerations > > = > > > > Following are the important aspects taken into account while designing > > the current RFC > > proposal: > > > > 1. Individual HW blocks can be muxed. (e.g. out of two HW blocks only > > one > can be used) > > 2. Position of the HW block in the pipeline can be programmable > > 3. LUTs can be one dimentional or three dimentional > > 4. Number of LUT entries can vary across platforms > > 5. Precision of LUT entries can vary across platforms > > 6. Distribution of LUT entries may vary. e.g Mutli-segmented, > > Logarithmic, > >Piece-Wise Linear(PWL) etc > > 7. There can be parameterized/non-parameterized fixed function HW > blocks. > >e.g. Just a hardware bit, to convert from one color space to another. > > 8. Custom non-standard HW implementation. > > 9. Leaving scope for some vendor defined pescriptive implementation if > required. > > 10.Scope to handle any modification in hardware as technology evolves > > > > The current proposal takes into account the above considerations while > > keeping the implementation as generic as possible leaving scope for future > additions or modifications. > > > > This proposal is also in line to the details mentioned by Simon's RFC > > covering all the aspects discussed in hackfest. > > > > > > Outline of the implementation > > > > > > Each Color Hardware block will be represented by a data structure > > d
Re: [PATCH 2/5] drm/debugfs: disallow debugfs access when device isn't registered
Hi Christian, > > > > > > During device bringup it might be that we can't access > > > > > > the debugfs files. > > > > > > Return -ENODEV until the registration is completed on access. > > > > > just wondering, if the device is not registered, how do we get > > > > > there? > > > > The workflow is: > > > > 1. Creation (DRM) > > > > 2. Initialization (Driver) > > > > 3. Registration (DRM) > > > > ... > > > > 4. Unregistration (DRM) > > > > 5. Deinitialization (Driver) > > > > 6. Destruction (DRM) > > > > > > > > It is possible that debugfs files are created during driver > > > > initialization, > > > > but Daniel insisted that they should not be accessible until the > > > > registration is done (which makes the other UAPI accessible as well). > > > makes sense, but then why not -EAGAIN, or -EBUSY? > > > > Good question. > > > > I think the main use case for this is between 4 and 6. E.g. a device > > which is hot removed and now in the process of being torn down. > > > > In this situation we might still have references from userspace (memory > > mapping etc...), so the drm file and with it the debugfs directory is > > still there but the physical device is gone. For the IOCTL UAPI we then > > also return -ENODEV as well, so this makes sense. > > > > The time between 1 and 3 is interesting as well, but here it's more like > > we couldn't get the device initialized and are now stuck. This happens > > sometimes during early hardware bringup and I still disagree with Daniel > > that we should block that (well on the other hand it's trivial for a > > developer to comment those checks out). > > Could I get an rb for this series or at least this patch from you? I took some time thinking of possible scenarios and use cases... What I was thinking, indeed, was scenario 1-3 and I also think that blocking is not the right thing. In any case the probability that this might happen is too low, not just in early bring up but also when modprobing where a little timer would do. For both cases, 1-3 and 4-6, I believe that -EBUSY would be better because the device is indeed busy in both cases. Anyway it's a tiny detail we are talking about here :) Reviewed-by: Andi Shyti Andi
RE: [RFC 01/33] drm/doc/rfc: Add RFC document for proposed Plane Color Pipeline
> -Original Message- > From: Harry Wentland > Sent: Wednesday, August 30, 2023 1:10 AM > To: Shankar, Uma ; intel-...@lists.freedesktop.org; > dri- > de...@lists.freedesktop.org > Cc: Borah, Chaitanya Kumar ; wayland- > de...@lists.freedesktop.org > Subject: Re: [RFC 01/33] drm/doc/rfc: Add RFC document for proposed Plane > Color > Pipeline > > > > On 2023-08-29 12:03, Uma Shankar wrote: > > Add the documentation for the new proposed Plane Color Pipeline. > > > > Co-developed-by: Chaitanya Kumar Borah > > > > Signed-off-by: Chaitanya Kumar Borah > > Signed-off-by: Uma Shankar > > --- > > .../gpu/rfc/plane_color_pipeline.rst | 394 ++ > > 1 file changed, 394 insertions(+) > > create mode 100644 Documentation/gpu/rfc/plane_color_pipeline.rst > > > > diff --git a/Documentation/gpu/rfc/plane_color_pipeline.rst > > b/Documentation/gpu/rfc/plane_color_pipeline.rst > > new file mode 100644 > > index ..60ce515b6ea7 > > --- /dev/null > > +++ b/Documentation/gpu/rfc/plane_color_pipeline.rst > > @@ -0,0 +1,394 @@ > > +=== > > + Plane Color Pipeline: A UAPI proposal > > +=== > > + > > +To build the proposal on, lets take the premise of a color pipeline > > +as shown below. > > + > > + +---+ > > + |RAM| > > + | +--++-++-+ | > > + | | FB 1 || FB 2 || FB N| | > > + | +--++-++-+ | > > + +---+ > > + | Plane Color Hardware Block | > > + ++ > > + | +---v-+ +---v---+ +---v--+ | > > + | | Plane A | | Plane B | | Plane N | | > > + | | Pre-CSC | | Pre-CSC | | Pre-CSC | | > > + | +---+-+ +---+---+ +---+--+ | > > + | | | || > > + | +---v-+ +---v---+ +---v--+ | > > + | |Plane A | | Plane B | | Plane N | | > > + | |CSC/CTM | | CSC/CTM | | CSC/CTM | | > > + | +---+-+ ++--+ ++-+ | > > + | | | | | > > + | +---v-+ +v--+ +v-+ | > > + | | Plane A | | Plane B | | Plane N | | > > + | |Post-CSC | | Post-CSC | | Post-CSC | | > > + | +---+-+ ++--+ ++-+ | > > + | | | | | > > + ++ > > ++--v--v---v---| > > +|| || > > +|| Pipe Blender|| > > ++++ > > +||| > > +|+---v--+ | > > +|| Pipe Pre-CSC| | > > +|| | | > > +|+---+--+ | > > +||Pipe Color | > > +|+---v--+ Hardware| > > +|| Pipe CSC/CTM| | > > +|| | | > > +|+---+--+ | > > +||| > > +|+---v--+ | > > +|| Pipe Post-CSC | | > > +|| | | > > +|+---+--+ | > > +||| > > ++-+ > > + | > > + v > > +Pipe Output > > + > > +Each plane consists of the following color blocks > > + * Pre-CSC : This block can used to linearize the input frame buffer data. > > + The linear data then can be further acted on by the following > > + color hardware blocks in the display hardware pipeline > > + > > + * CSC/CTM: Used to program color transformation matrix, this block is used > > +to perform color space conversions like BT2020 to BT709 or > > BT601 > > +etc. This block acts on the linearized data coming from the > > +Pre-CSC HW block. > > + > > + * Post-CSC: This HW block can be used to non-linearize frame buffer data > > to > > + match the sink. Another use case of it could be to perform > > Tone > > + mapping for HDR use-cases. > > + > > +Data from multiple planes will then be fed to pipe/crtc where it will get > > blended. > > +There is a similar set of HW blocks available at pipe/crtc level > > +which acts on this blended data. > > + > > +Below is a sample usecase fo video playback with sub-titles and > > +playback controls > > + > > +┌┐┌─┐ ┌─┐┌─┐ > > +│FB1 ││PRE
Re: [Intel-gfx] [PATCH 0/4] drm/amd/display: stop using drm_edid_override_connector_update()
On Wed, Aug 30, 2023 at 10:29:46AM +0300, Jani Nikula wrote: > Upstream code should be reviewed in public. Yup -Sima -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
Re: [PATCH v11] drm: Add initial ci/ subdirectory
On Tue, Aug 22, 2023 at 04:26:06PM +0200, Daniel Vetter wrote: > On Fri, Aug 11, 2023 at 02:19:53PM -0300, Helen Koike wrote: > > From: Tomeu Vizoso > > > > Developers can easily execute several tests on different devices > > by just pushing their branch to their fork in a repository hosted > > on gitlab.freedesktop.org which has an infrastructure to run jobs > > in several runners and farms with different devices. > > > > There are also other automated tools that uprev dependencies, > > monitor the infra, and so on that are already used by the Mesa > > project, and we can reuse them too. > > > > Also, store expectations about what the DRM drivers are supposed > > to pass in the IGT test suite. By storing the test expectations > > along with the code, we can make sure both stay in sync with each > > other so we can know when a code change breaks those expectations. > > > > Also, include a configuration file that points to the out-of-tree > > CI scripts. > > > > This will allow all contributors to drm to reuse the infrastructure > > already in gitlab.freedesktop.org to test the driver on several > > generations of the hardware. > > > > Signed-off-by: Tomeu Vizoso > > Signed-off-by: Helen Koike > > Acked-by: Daniel Stone > > Acked-by: Rob Clark > > Tested-by: Rob Clark > > Ok I pushed this into a topic/drm-ci branch in drm.git and asked sfr to > include that branch in linux-next. > > But also I'd like to see a lot more acks here, we should be able to at > least pile up a bunch of (driver) maintainers from drm-misc in support of > this. Also maybe media, at least I've heard noises that they're maybe > interested too? Plus anyone else, the more the better. I'm not really convinced by that approach at all, and most of the issues I see are shown by the follow-up series here: https://lore.kernel.org/dri-devel/20230825122435.316272-1-vignesh.ra...@collabora.com/ * We hardcode a CI farm setup into the kernel * We cannot trust that the code being run is actually the one being pushed into gitlab * IMO, and I know we disagree here, any IGT test we enable for a given platform should work, period. Allowing failures and flaky tests just sweeps whatever issue is there under the rug. If the test is at fault, we should fix the test, if the driver / kernel is at fault, then I certainly want to know about it. * This then leads to patches like this one: https://lore.kernel.org/dri-devel/20230825122435.316272-6-vignesh.ra...@collabora.com/ Which (and it's definitely not the author's fault) are just plain unreadable, reproducable or auditable by anyone not heavily involved in the CI farm operations and the platforms being tested. That being said, I don't have anything better to suggest than what I already did, and it looks like I'm alone in thinking that those are problems, so feel free to add my ack if you want to. Maxime signature.asc Description: PGP signature
Re: [PATCH 3/6] drm/edid: parse source physical address
On 24/08/2023 15:46, Jani Nikula wrote: > CEC needs the source physical address. Parsing it is trivial with the > existing EDID CEA DB infrastructure. > > Default to CEC_PHYS_ADDR_INVALID (0x) instead of 0 to cater for > easier CEC usage. > > Cc: Hans Verkuil > Cc: linux-me...@vger.kernel.org > Signed-off-by: Jani Nikula Reviewed-by: Hans Verkuil Regards, Hans > --- > drivers/gpu/drm/drm_edid.c | 5 + > include/drm/drm_connector.h | 8 > 2 files changed, 13 insertions(+) > > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c > index 1dbb15439468..39dd3f694544 100644 > --- a/drivers/gpu/drm/drm_edid.c > +++ b/drivers/gpu/drm/drm_edid.c > @@ -29,6 +29,7 @@ > */ > > #include > +#include > #include > #include > #include > @@ -6192,6 +6193,8 @@ drm_parse_hdmi_vsdb_video(struct drm_connector > *connector, const u8 *db) > > info->is_hdmi = true; > > + info->source_physical_address = (db[4] << 8) | db[5]; > + > if (len >= 6) > info->dvi_dual = db[6] & 1; > if (len >= 7) > @@ -6470,6 +6473,8 @@ static void drm_reset_display_info(struct drm_connector > *connector) > info->vics_len = 0; > > info->quirks = 0; > + > + info->source_physical_address = CEC_PHYS_ADDR_INVALID; > } > > static void update_displayid_info(struct drm_connector *connector, > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h > index d300fde6c1a4..40a5e7acf2fa 100644 > --- a/include/drm/drm_connector.h > +++ b/include/drm/drm_connector.h > @@ -816,6 +816,14 @@ struct drm_display_info { >* @quirks: EDID based quirks. Internal to EDID parsing. >*/ > u32 quirks; > + > + /** > + * @source_physical_address: Source Physical Address from HDMI > + * Vendor-Specific Data Block, for CEC usage. > + * > + * Defaults to CEC_PHYS_ADDR_INVALID (0x). > + */ > + u16 source_physical_address; > }; > > int drm_display_info_set_bus_formats(struct drm_display_info *info,
Re: [PATCH 4/6] drm/cec: add drm_dp_cec_attach() as the non-edid version of set edid
On 24/08/2023 15:46, Jani Nikula wrote: > Connectors have source physical address available in display > info. There's no need to parse the EDID again for this. Add > drm_dp_cec_attach() to do this. > > Seems like the set_edid/unset_edid naming is a bit specific now that > there's no need to pass the EDID at all, so aim for attach/detach going > forward. > > Cc: Hans Verkuil > Cc: linux-me...@vger.kernel.org > Signed-off-by: Jani Nikula > --- > drivers/gpu/drm/display/drm_dp_cec.c | 22 +++--- > include/drm/display/drm_dp_helper.h | 6 ++ > 2 files changed, 25 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/display/drm_dp_cec.c > b/drivers/gpu/drm/display/drm_dp_cec.c > index ae39dc794190..da7a7d357446 100644 > --- a/drivers/gpu/drm/display/drm_dp_cec.c > +++ b/drivers/gpu/drm/display/drm_dp_cec.c > @@ -297,7 +297,7 @@ static void drm_dp_cec_unregister_work(struct work_struct > *work) > * were unchanged and just update the CEC physical address. Otherwise > * unregister the old CEC adapter and create a new one. > */ > -void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid) > +void drm_dp_cec_attach(struct drm_dp_aux *aux, u16 source_physical_address) > { > struct drm_connector *connector = aux->cec.connector; > u32 cec_caps = CEC_CAP_DEFAULTS | CEC_CAP_NEEDS_HPD | > @@ -339,7 +339,7 @@ void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const > struct edid *edid) > if (aux->cec.adap->capabilities == cec_caps && > aux->cec.adap->available_log_addrs == num_las) { > /* Unchanged, so just set the phys addr */ > - cec_s_phys_addr_from_edid(aux->cec.adap, edid); > + cec_s_phys_addr(adap, source_physical_address, false); As the kernel test robot indicated, this does not compile, this should be aux->cec.adap. > goto unlock; > } > /* > @@ -370,11 +370,27 @@ void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const > struct edid *edid) >* from drm_dp_cec_register_connector() edid == NULL, so in >* that case the phys addr is just invalidated. >*/ > - cec_s_phys_addr_from_edid(aux->cec.adap, edid); > + cec_s_phys_addr(adap, source_physical_address, false); > } > unlock: > mutex_unlock(&aux->cec.lock); > } > +EXPORT_SYMBOL(drm_dp_cec_attach); > + > +/* > + * Note: Prefer calling drm_dp_cec_attach() with > + * connector->display_info.source_physical_address if possible. > + */ > +void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid) > +{ > + u16 source_physical_address = CEC_PHYS_ADDR_INVALID; > + > + if (edid && edid->extensions) And this source needs to include , also as found by the kernel test robot. Regards, Hans > + pa = cec_get_edid_phys_addr((const u8 *)edid, > + EDID_LENGTH * (edid->extensions + > 1), NULL); > + > + drm_dp_cec_attach(aux, source_physical_address); > +} > EXPORT_SYMBOL(drm_dp_cec_set_edid); > > /* > diff --git a/include/drm/display/drm_dp_helper.h > b/include/drm/display/drm_dp_helper.h > index 86f24a759268..3369104e2d25 100644 > --- a/include/drm/display/drm_dp_helper.h > +++ b/include/drm/display/drm_dp_helper.h > @@ -699,6 +699,7 @@ void drm_dp_cec_irq(struct drm_dp_aux *aux); > void drm_dp_cec_register_connector(struct drm_dp_aux *aux, > struct drm_connector *connector); > void drm_dp_cec_unregister_connector(struct drm_dp_aux *aux); > +void drm_dp_cec_attach(struct drm_dp_aux *aux, u16 source_physical_address); > void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid); > void drm_dp_cec_unset_edid(struct drm_dp_aux *aux); > #else > @@ -716,6 +717,11 @@ static inline void > drm_dp_cec_unregister_connector(struct drm_dp_aux *aux) > { > } > > +static inline void drm_dp_cec_attach(struct drm_dp_aux *aux, > + u16 source_physical_address) > +{ > +} > + > static inline void drm_dp_cec_set_edid(struct drm_dp_aux *aux, > const struct edid *edid) > {
Re: [PATCH 5/6] drm/i915/cec: switch to setting physical address directly
On 24/08/2023 15:46, Jani Nikula wrote: > Avoid parsing the EDID again for source physical address. Also gets rids > of a few remaining raw EDID usages. > > Cc: Hans Verkuil > Cc: linux-me...@vger.kernel.org > Signed-off-by: Jani Nikula Reviewed-by: Hans Verkuil Regards, Hans > --- > drivers/gpu/drm/i915/display/intel_dp.c | 7 ++- > drivers/gpu/drm/i915/display/intel_hdmi.c | 5 ++--- > 2 files changed, 4 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c > b/drivers/gpu/drm/i915/display/intel_dp.c > index 7067ee3a4bd3..c4b8e0e74c15 100644 > --- a/drivers/gpu/drm/i915/display/intel_dp.c > +++ b/drivers/gpu/drm/i915/display/intel_dp.c > @@ -5198,7 +5198,6 @@ intel_dp_set_edid(struct intel_dp *intel_dp) > struct drm_i915_private *i915 = dp_to_i915(intel_dp); > struct intel_connector *connector = intel_dp->attached_connector; > const struct drm_edid *drm_edid; > - const struct edid *edid; > bool vrr_capable; > > intel_dp_unset_edid(intel_dp); > @@ -5216,10 +5215,8 @@ intel_dp_set_edid(struct intel_dp *intel_dp) > intel_dp_update_dfp(intel_dp, drm_edid); > intel_dp_update_420(intel_dp); > > - /* FIXME: Get rid of drm_edid_raw() */ > - edid = drm_edid_raw(drm_edid); > - > - drm_dp_cec_set_edid(&intel_dp->aux, edid); > + drm_dp_cec_attach(&intel_dp->aux, > + connector->base.display_info.source_physical_address); > } > > static void > diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c > b/drivers/gpu/drm/i915/display/intel_hdmi.c > index aa9915098dda..5d6255ee8b54 100644 > --- a/drivers/gpu/drm/i915/display/intel_hdmi.c > +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c > @@ -2482,9 +2482,8 @@ intel_hdmi_set_edid(struct drm_connector *connector) > > intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref); > > - /* FIXME: Get rid of drm_edid_raw() */ > - cec_notifier_set_phys_addr_from_edid(intel_hdmi->cec_notifier, > - drm_edid_raw(drm_edid)); > + cec_notifier_set_phys_addr(intel_hdmi->cec_notifier, > + > connector->display_info.source_physical_address); > > return connected; > }
Re: [PATCH 6/6] media: cec: core: add note about *_from_edid() function usage in drm
On 24/08/2023 15:46, Jani Nikula wrote: > In the drm subsystem, the source physical address is, in most cases, > available without having to parse the EDID again. Add notes about > preferring to use the pre-parsed address instead. > > Cc: Hans Verkuil > Cc: linux-me...@vger.kernel.org > Signed-off-by: Jani Nikula > --- > drivers/media/cec/core/cec-adap.c | 4 > drivers/media/cec/core/cec-notifier.c | 4 > 2 files changed, 8 insertions(+) > > diff --git a/drivers/media/cec/core/cec-adap.c > b/drivers/media/cec/core/cec-adap.c > index 241b1621b197..2c627ed611ed 100644 > --- a/drivers/media/cec/core/cec-adap.c > +++ b/drivers/media/cec/core/cec-adap.c > @@ -1688,6 +1688,10 @@ void cec_s_phys_addr(struct cec_adapter *adap, u16 > phys_addr, bool block) > } > EXPORT_SYMBOL_GPL(cec_s_phys_addr); > > +/* > + * Note: In the drm subsystem, prefer calling cec_s_phys_addr() with > + * connector->display_info.source_physical_address if possible. > + */ I would rephrase this: /* * Note: in the drm subsystem, prefer calling (if possible): * * cec_s_phys_addr(adap, connector->display_info.source_physical_address, false); */ I think it is important to indicate that the last argument should be 'false'. > void cec_s_phys_addr_from_edid(struct cec_adapter *adap, > const struct edid *edid) > { > diff --git a/drivers/media/cec/core/cec-notifier.c > b/drivers/media/cec/core/cec-notifier.c > index 389dc664b211..13f043b3025b 100644 > --- a/drivers/media/cec/core/cec-notifier.c > +++ b/drivers/media/cec/core/cec-notifier.c > @@ -195,6 +195,10 @@ void cec_notifier_set_phys_addr(struct cec_notifier *n, > u16 pa) > } > EXPORT_SYMBOL_GPL(cec_notifier_set_phys_addr); > > +/* > + * Note: In the drm subsystem, prefer calling cec_notifier_set_phys_addr() > with > + * connector->display_info.source_physical_address if possible. > + */ This comment is fine, there is no similar last argument here. But perhaps it is good to use a similar format as above. Up to you. > void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n, > const struct edid *edid) > { Regards, Hans
Re: [PATCH v2 2/6] drm/panfrost: Add fdinfo support GPU load metrics
On Thu, 24 Aug 2023 02:34:45 +0100 Adrián Larumbe wrote: > The drm-stats fdinfo tags made available to user space are drm-engine, > drm-cycles, drm-max-freq and drm-curfreq, one per job slot. Pretty sure this has already been discussed, but it's probably worth mentioning that drm-cycles is not accurate, it just gives you a rough idea of how much GPU cycles were dedicated to a context (just like drm-engine elapsed-ns is giving you an approximation of the GPU utilization). This comes from 2 factors: 1. We're dependent on the time the kernel/CPU takes to process the GPU interrupt. 2. The pipelining done by the Job Manager (2 job slots per engine) implies that you can't really know how much time each job spent on the GPU. When these jobs are coming from the same context, that's not a problem, but when they don't, it's impossible to have a clear split. I'd really like to have that mentioned somewhere in the code+commit message to lower users expectation. > > This deviates from standard practice in other DRM drivers, where a single > set of key:value pairs is provided for the whole render engine. However, > Panfrost has separate queues for fragment and vertex/tiler jobs, so a > decision was made to calculate bus cycles and workload times separately. > > Maximum operating frequency is calculated at devfreq initialisation time. > Current frequency is made available to user space because nvtop uses it > when performing engine usage calculations. > > Signed-off-by: Adrián Larumbe > --- > drivers/gpu/drm/panfrost/panfrost_devfreq.c | 8 > drivers/gpu/drm/panfrost/panfrost_devfreq.h | 3 ++ > drivers/gpu/drm/panfrost/panfrost_device.h | 13 ++ > drivers/gpu/drm/panfrost/panfrost_drv.c | 45 - > drivers/gpu/drm/panfrost/panfrost_job.c | 30 ++ > drivers/gpu/drm/panfrost/panfrost_job.h | 4 ++ > 6 files changed, 102 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c > b/drivers/gpu/drm/panfrost/panfrost_devfreq.c > index 58dfb15a8757..28caffc689e2 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c > +++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c > @@ -58,6 +58,7 @@ static int panfrost_devfreq_get_dev_status(struct device > *dev, > spin_lock_irqsave(&pfdevfreq->lock, irqflags); > > panfrost_devfreq_update_utilization(pfdevfreq); > + pfdevfreq->current_frequency = status->current_frequency; > > status->total_time = ktime_to_ns(ktime_add(pfdevfreq->busy_time, > pfdevfreq->idle_time)); > @@ -117,6 +118,7 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) > struct devfreq *devfreq; > struct thermal_cooling_device *cooling; > struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq; > + unsigned long freq = ULONG_MAX; > > if (pfdev->comp->num_supplies > 1) { > /* > @@ -172,6 +174,12 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) > return ret; > } > > + /* Find the fastest defined rate */ > + opp = dev_pm_opp_find_freq_floor(dev, &freq); > + if (IS_ERR(opp)) > + return PTR_ERR(opp); > + pfdevfreq->fast_rate = freq; > + > dev_pm_opp_put(opp); > > /* > diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.h > b/drivers/gpu/drm/panfrost/panfrost_devfreq.h > index 1514c1f9d91c..48dbe185f206 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_devfreq.h > +++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.h > @@ -19,6 +19,9 @@ struct panfrost_devfreq { > struct devfreq_simple_ondemand_data gov_data; > bool opp_of_table_added; > > + unsigned long current_frequency; > + unsigned long fast_rate; > + > ktime_t busy_time; > ktime_t idle_time; > ktime_t time_last_update; > diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h > b/drivers/gpu/drm/panfrost/panfrost_device.h > index b0126b9fbadc..680f298fd1a9 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_device.h > +++ b/drivers/gpu/drm/panfrost/panfrost_device.h > @@ -24,6 +24,7 @@ struct panfrost_perfcnt; > > #define NUM_JOB_SLOTS 3 > #define MAX_PM_DOMAINS 5 > +#define MAX_SLOT_NAME_LEN 10 > > struct panfrost_features { > u16 id; > @@ -135,12 +136,24 @@ struct panfrost_mmu { > struct list_head list; > }; > > +struct drm_info_gpu { > + unsigned int maxfreq; > + > + struct engine_info { > + unsigned long long elapsed_ns; > + unsigned long long cycles; > + char name[MAX_SLOT_NAME_LEN]; > + } engines[NUM_JOB_SLOTS]; > +}; > + > struct panfrost_file_priv { > struct panfrost_device *pfdev; > > struct drm_sched_entity sched_entity[NUM_JOB_SLOTS]; > > struct panfrost_mmu *mmu; > + > + struct drm_info_gpu fdinfo; > }; > > static inline struct panfrost_device *to_panfrost_device(struct drm_device > *ddev) > diff --git a/drivers/gpu/drm/pa
Re: [PATCH] drm/tegra: Remove existing framebuffer only if we support display
Hi Am 25.08.23 um 15:22 schrieb Thierry Reding: From: Thierry Reding Tegra DRM doesn't support display on Tegra234 and later, so make sure not to remove any existing framebuffers in that case. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/drm.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index b1e1a78e30c6..7a38dadbc264 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -1220,9 +1220,11 @@ static int host1x_drm_probe(struct host1x_device *dev) drm_mode_config_reset(drm); - err = drm_aperture_remove_framebuffers(&tegra_drm_driver); - if (err < 0) - goto hub; + if (drm->mode_config.num_crtc > 0) { If you don't support the hardware, wouldn't it be better to return -ENODEV if !num_crtc? Best regards Thomas + err = drm_aperture_remove_framebuffers(&tegra_drm_driver); + if (err < 0) + goto hub; + } err = drm_dev_register(drm, 0); if (err < 0) -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg) OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH 4/6] drm/cec: add drm_dp_cec_attach() as the non-edid version of set edid
On Wed, 30 Aug 2023, Hans Verkuil wrote: > On 24/08/2023 15:46, Jani Nikula wrote: >> Connectors have source physical address available in display >> info. There's no need to parse the EDID again for this. Add >> drm_dp_cec_attach() to do this. >> >> Seems like the set_edid/unset_edid naming is a bit specific now that >> there's no need to pass the EDID at all, so aim for attach/detach going >> forward. >> >> Cc: Hans Verkuil >> Cc: linux-me...@vger.kernel.org >> Signed-off-by: Jani Nikula >> --- >> drivers/gpu/drm/display/drm_dp_cec.c | 22 +++--- >> include/drm/display/drm_dp_helper.h | 6 ++ >> 2 files changed, 25 insertions(+), 3 deletions(-) >> >> diff --git a/drivers/gpu/drm/display/drm_dp_cec.c >> b/drivers/gpu/drm/display/drm_dp_cec.c >> index ae39dc794190..da7a7d357446 100644 >> --- a/drivers/gpu/drm/display/drm_dp_cec.c >> +++ b/drivers/gpu/drm/display/drm_dp_cec.c >> @@ -297,7 +297,7 @@ static void drm_dp_cec_unregister_work(struct >> work_struct *work) >> * were unchanged and just update the CEC physical address. Otherwise >> * unregister the old CEC adapter and create a new one. >> */ >> -void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid) >> +void drm_dp_cec_attach(struct drm_dp_aux *aux, u16 source_physical_address) >> { >> struct drm_connector *connector = aux->cec.connector; >> u32 cec_caps = CEC_CAP_DEFAULTS | CEC_CAP_NEEDS_HPD | >> @@ -339,7 +339,7 @@ void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const >> struct edid *edid) >> if (aux->cec.adap->capabilities == cec_caps && >> aux->cec.adap->available_log_addrs == num_las) { >> /* Unchanged, so just set the phys addr */ >> -cec_s_phys_addr_from_edid(aux->cec.adap, edid); >> +cec_s_phys_addr(adap, source_physical_address, false); > > As the kernel test robot indicated, this does not compile, this should > be aux->cec.adap. > >> goto unlock; >> } >> /* >> @@ -370,11 +370,27 @@ void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const >> struct edid *edid) >> * from drm_dp_cec_register_connector() edid == NULL, so in >> * that case the phys addr is just invalidated. >> */ >> -cec_s_phys_addr_from_edid(aux->cec.adap, edid); >> +cec_s_phys_addr(adap, source_physical_address, false); >> } >> unlock: >> mutex_unlock(&aux->cec.lock); >> } >> +EXPORT_SYMBOL(drm_dp_cec_attach); >> + >> +/* >> + * Note: Prefer calling drm_dp_cec_attach() with >> + * connector->display_info.source_physical_address if possible. >> + */ >> +void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid) >> +{ >> +u16 source_physical_address = CEC_PHYS_ADDR_INVALID; >> + >> +if (edid && edid->extensions) > > And this source needs to include , also as found by > the kernel test robot. Yes, very embarrassing, I sent the v2 in reply [1]. BR, Jani. [1] https://patchwork.freedesktop.org/patch/msgid/20230825130120.1250089-1-jani.nik...@intel.com > > Regards, > > Hans > >> +pa = cec_get_edid_phys_addr((const u8 *)edid, >> +EDID_LENGTH * (edid->extensions + >> 1), NULL); >> + >> +drm_dp_cec_attach(aux, source_physical_address); >> +} >> EXPORT_SYMBOL(drm_dp_cec_set_edid); >> >> /* >> diff --git a/include/drm/display/drm_dp_helper.h >> b/include/drm/display/drm_dp_helper.h >> index 86f24a759268..3369104e2d25 100644 >> --- a/include/drm/display/drm_dp_helper.h >> +++ b/include/drm/display/drm_dp_helper.h >> @@ -699,6 +699,7 @@ void drm_dp_cec_irq(struct drm_dp_aux *aux); >> void drm_dp_cec_register_connector(struct drm_dp_aux *aux, >> struct drm_connector *connector); >> void drm_dp_cec_unregister_connector(struct drm_dp_aux *aux); >> +void drm_dp_cec_attach(struct drm_dp_aux *aux, u16 source_physical_address); >> void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid); >> void drm_dp_cec_unset_edid(struct drm_dp_aux *aux); >> #else >> @@ -716,6 +717,11 @@ static inline void >> drm_dp_cec_unregister_connector(struct drm_dp_aux *aux) >> { >> } >> >> +static inline void drm_dp_cec_attach(struct drm_dp_aux *aux, >> + u16 source_physical_address) >> +{ >> +} >> + >> static inline void drm_dp_cec_set_edid(struct drm_dp_aux *aux, >> const struct edid *edid) >> { > -- Jani Nikula, Intel Open Source Graphics Center
Re: [PATCH v2] drm/cec: add drm_dp_cec_attach() as the non-edid version of set edid
Hi Jani, Sorry, I missed the v2. On 25/08/2023 15:01, Jani Nikula wrote: > Connectors have source physical address available in display > info. There's no need to parse the EDID again for this. Add > drm_dp_cec_attach() to do this. > > Seems like the set_edid/unset_edid naming is a bit specific now that > there's no need to pass the EDID at all, so aim for attach/detach going > forward. > > v2: Fix the embarrashing build failures > > Cc: Hans Verkuil > Cc: linux-me...@vger.kernel.org > Signed-off-by: Jani Nikula Reviewed-by: Hans Verkuil Regards, Hans > --- > drivers/gpu/drm/display/drm_dp_cec.c | 23 --- > include/drm/display/drm_dp_helper.h | 6 ++ > 2 files changed, 26 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/display/drm_dp_cec.c > b/drivers/gpu/drm/display/drm_dp_cec.c > index ae39dc794190..007ceb281d00 100644 > --- a/drivers/gpu/drm/display/drm_dp_cec.c > +++ b/drivers/gpu/drm/display/drm_dp_cec.c > @@ -14,6 +14,7 @@ > #include > #include > #include > +#include > > /* > * Unfortunately it turns out that we have a chicken-and-egg situation > @@ -297,7 +298,7 @@ static void drm_dp_cec_unregister_work(struct work_struct > *work) > * were unchanged and just update the CEC physical address. Otherwise > * unregister the old CEC adapter and create a new one. > */ > -void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid) > +void drm_dp_cec_attach(struct drm_dp_aux *aux, u16 source_physical_address) > { > struct drm_connector *connector = aux->cec.connector; > u32 cec_caps = CEC_CAP_DEFAULTS | CEC_CAP_NEEDS_HPD | > @@ -339,7 +340,7 @@ void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const > struct edid *edid) > if (aux->cec.adap->capabilities == cec_caps && > aux->cec.adap->available_log_addrs == num_las) { > /* Unchanged, so just set the phys addr */ > - cec_s_phys_addr_from_edid(aux->cec.adap, edid); > + cec_s_phys_addr(aux->cec.adap, source_physical_address, > false); > goto unlock; > } > /* > @@ -370,11 +371,27 @@ void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const > struct edid *edid) >* from drm_dp_cec_register_connector() edid == NULL, so in >* that case the phys addr is just invalidated. >*/ > - cec_s_phys_addr_from_edid(aux->cec.adap, edid); > + cec_s_phys_addr(aux->cec.adap, source_physical_address, false); > } > unlock: > mutex_unlock(&aux->cec.lock); > } > +EXPORT_SYMBOL(drm_dp_cec_attach); > + > +/* > + * Note: Prefer calling drm_dp_cec_attach() with > + * connector->display_info.source_physical_address if possible. > + */ > +void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid) > +{ > + u16 pa = CEC_PHYS_ADDR_INVALID; > + > + if (edid && edid->extensions) > + pa = cec_get_edid_phys_addr((const u8 *)edid, > + EDID_LENGTH * (edid->extensions + > 1), NULL); > + > + drm_dp_cec_attach(aux, pa); > +} > EXPORT_SYMBOL(drm_dp_cec_set_edid); > > /* > diff --git a/include/drm/display/drm_dp_helper.h > b/include/drm/display/drm_dp_helper.h > index 86f24a759268..3369104e2d25 100644 > --- a/include/drm/display/drm_dp_helper.h > +++ b/include/drm/display/drm_dp_helper.h > @@ -699,6 +699,7 @@ void drm_dp_cec_irq(struct drm_dp_aux *aux); > void drm_dp_cec_register_connector(struct drm_dp_aux *aux, > struct drm_connector *connector); > void drm_dp_cec_unregister_connector(struct drm_dp_aux *aux); > +void drm_dp_cec_attach(struct drm_dp_aux *aux, u16 source_physical_address); > void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid); > void drm_dp_cec_unset_edid(struct drm_dp_aux *aux); > #else > @@ -716,6 +717,11 @@ static inline void > drm_dp_cec_unregister_connector(struct drm_dp_aux *aux) > { > } > > +static inline void drm_dp_cec_attach(struct drm_dp_aux *aux, > + u16 source_physical_address) > +{ > +} > + > static inline void drm_dp_cec_set_edid(struct drm_dp_aux *aux, > const struct edid *edid) > {
Re: [PATCH v2 3/6] drm/panfrost: Add fdinfo support for memory stats
On Thu, 24 Aug 2023 02:34:46 +0100 Adrián Larumbe wrote: > A new DRM GEM object function is added so that drm_show_memory_stats can > provider more accurate memory usage numbers. s/provider/provide/ > > Ideally, in panfrost_gem_status, the BO's purgeable flag would be checked > after locking the driver's shrinker mutex, but drm_show_memory_stats takes > over the drm file's object handle database spinlock, so there's potential > for a race condition here. Yeah, I don't think it matters much if we report a BO non-purgeable, and this BO becomes purgeable in the meantime. You'd have the same problem > > Signed-off-by: Adrián Larumbe > --- > drivers/gpu/drm/panfrost/panfrost_drv.c | 9 +++-- > drivers/gpu/drm/panfrost/panfrost_gem.c | 12 > drivers/gpu/drm/panfrost/panfrost_gem.h | 1 + > 3 files changed, 20 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c > b/drivers/gpu/drm/panfrost/panfrost_drv.c > index 3fd372301019..93d5f5538c0b 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_drv.c > +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c > @@ -440,11 +440,14 @@ static int panfrost_ioctl_madvise(struct drm_device > *dev, void *data, > args->retained = drm_gem_shmem_madvise(&bo->base, args->madv); > > if (args->retained) { > - if (args->madv == PANFROST_MADV_DONTNEED) > + if (args->madv == PANFROST_MADV_DONTNEED) { > list_move_tail(&bo->base.madv_list, > &pfdev->shrinker_list); > - else if (args->madv == PANFROST_MADV_WILLNEED) > + bo->is_purgable = true; > + } else if (args->madv == PANFROST_MADV_WILLNEED) { > list_del_init(&bo->base.madv_list); > + bo->is_purgable = false; Should we really flag the BO as purgeable if it's already been evicted (args->retained == false)? > + } > } > > out_unlock_mappings: > @@ -559,6 +562,8 @@ static void panfrost_show_fdinfo(struct drm_printer *p, > struct drm_file *file) > struct panfrost_device *pfdev = dev->dev_private; > > panfrost_gpu_show_fdinfo(pfdev, file->driver_priv, p); > + > + drm_show_memory_stats(p, file); > } > > static const struct file_operations panfrost_drm_driver_fops = { > diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c > b/drivers/gpu/drm/panfrost/panfrost_gem.c > index 3c812fbd126f..aea16b0e4dda 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_gem.c > +++ b/drivers/gpu/drm/panfrost/panfrost_gem.c > @@ -195,6 +195,17 @@ static int panfrost_gem_pin(struct drm_gem_object *obj) > return drm_gem_shmem_pin(&bo->base); > } > > +static enum drm_gem_object_status panfrost_gem_status(struct drm_gem_object > *obj) > +{ > + struct panfrost_gem_object *bo = to_panfrost_bo(obj); > + enum drm_gem_object_status res = 0; > + > + res |= (bo->is_purgable) ? DRM_GEM_OBJECT_PURGEABLE : 0; Why not checking bo->base.madv here instead of adding an is_purgeable field? > + > + res |= (bo->base.pages) ? DRM_GEM_OBJECT_RESIDENT : 0; Does it make sense to have DRM_GEM_OBJECT_PURGEABLE set when DRM_GEM_OBJECT_RESIDENT is not? > + > + return res; > +} > static const struct drm_gem_object_funcs panfrost_gem_funcs = { > .free = panfrost_gem_free_object, > .open = panfrost_gem_open, > @@ -206,6 +217,7 @@ static const struct drm_gem_object_funcs > panfrost_gem_funcs = { > .vmap = drm_gem_shmem_object_vmap, > .vunmap = drm_gem_shmem_object_vunmap, > .mmap = drm_gem_shmem_object_mmap, > + .status = panfrost_gem_status, > .vm_ops = &drm_gem_shmem_vm_ops, > }; > > diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.h > b/drivers/gpu/drm/panfrost/panfrost_gem.h > index ad2877eeeccd..e06f7ceb8f73 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_gem.h > +++ b/drivers/gpu/drm/panfrost/panfrost_gem.h > @@ -38,6 +38,7 @@ struct panfrost_gem_object { > > bool noexec :1; > bool is_heap:1; > + bool is_purgable:1; > }; > > struct panfrost_gem_mapping {
Re: [PATCH v2 4/6] drm/drm_file: Add DRM obj's RSS reporting function for fdinfo
On Thu, 24 Aug 2023 02:34:47 +0100 Adrián Larumbe wrote: > Some BO's might be mapped onto physical memory chunkwise and on demand, > like Panfrost's tiler heap. In this case, even though the > drm_gem_shmem_object page array might already be allocated, only a very > small fraction of the BO is currently backed by system memory, but > drm_show_memory_stats will then proceed to add its entire virtual size to > the file's total resident size regardless. > > This led to very unrealistic RSS sizes being reckoned for Panfrost, where > said tiler heap buffer is initially allocated with a virtual size of 128 > MiB, but only a small part of it will eventually be backed by system memory > after successive GPU page faults. > > Provide a new DRM object generic function that would allow drivers to > return a more accurate RSS size for their BOs. > > Signed-off-by: Adrián Larumbe Reviewed-by: Boris Brezillon > --- > drivers/gpu/drm/drm_file.c | 5 - > include/drm/drm_gem.h | 9 + > 2 files changed, 13 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c > index 883d83bc0e3d..762965e3d503 100644 > --- a/drivers/gpu/drm/drm_file.c > +++ b/drivers/gpu/drm/drm_file.c > @@ -944,7 +944,10 @@ void drm_show_memory_stats(struct drm_printer *p, struct > drm_file *file) > } > > if (s & DRM_GEM_OBJECT_RESIDENT) { > - status.resident += obj->size; > + if (obj->funcs && obj->funcs->rss) > + status.resident += obj->funcs->rss(obj); > + else > + status.resident += obj->size; > } else { > /* If already purged or not yet backed by pages, don't >* count it as purgeable: > diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h > index c0b13c43b459..78ed9fab6044 100644 > --- a/include/drm/drm_gem.h > +++ b/include/drm/drm_gem.h > @@ -208,6 +208,15 @@ struct drm_gem_object_funcs { >*/ > enum drm_gem_object_status (*status)(struct drm_gem_object *obj); > > + /** > + * @rss: > + * > + * Return resident size of the object in physical memory. > + * > + * Called by drm_show_memory_stats(). > + */ > + size_t (*rss)(struct drm_gem_object *obj); > + > /** >* @vm_ops: >*
Re: [PATCH v2 1/6] drm/panfrost: Add cycle count GPU register definitions
On Thu, 24 Aug 2023 02:34:44 +0100 Adrián Larumbe wrote: > These GPU registers will be used when programming the cycle counter, which > we need for providing accurate fdinfo drm-cycles values to user space. > > Signed-off-by: Adrián Larumbe Reviewed-by: Boris Brezillon > --- > drivers/gpu/drm/panfrost/panfrost_regs.h | 5 + > 1 file changed, 5 insertions(+) > > diff --git a/drivers/gpu/drm/panfrost/panfrost_regs.h > b/drivers/gpu/drm/panfrost/panfrost_regs.h > index 919f44ac853d..55ec807550b3 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_regs.h > +++ b/drivers/gpu/drm/panfrost/panfrost_regs.h > @@ -46,6 +46,8 @@ > #define GPU_CMD_SOFT_RESET 0x01 > #define GPU_CMD_PERFCNT_CLEAR 0x03 > #define GPU_CMD_PERFCNT_SAMPLE 0x04 > +#define GPU_CMD_CYCLE_COUNT_START 0x05 > +#define GPU_CMD_CYCLE_COUNT_STOP 0x06 > #define GPU_CMD_CLEAN_CACHES 0x07 > #define GPU_CMD_CLEAN_INV_CACHES 0x08 > #define GPU_STATUS 0x34 > @@ -73,6 +75,9 @@ > #define GPU_PRFCNT_TILER_EN 0x74 > #define GPU_PRFCNT_MMU_L2_EN 0x7c > > +#define GPU_CYCLE_COUNT_LO 0x90 > +#define GPU_CYCLE_COUNT_HI 0x94 > + > #define GPU_THREAD_MAX_THREADS 0x0A0 /* (RO) Maximum number > of threads per core */ > #define GPU_THREAD_MAX_WORKGROUP_SIZE0x0A4 /* (RO) Maximum > workgroup size */ > #define GPU_THREAD_MAX_BARRIER_SIZE 0x0A8 /* (RO) Maximum threads waiting > at a barrier */
Re: [PATCH v2 5/6] drm/panfrost: Implement generic DRM object RSS reporting function
On Thu, 24 Aug 2023 02:34:48 +0100 Adrián Larumbe wrote: > BO's RSS is updated every time new pages are allocated and mapped for the > object, either in its entirety at creation time for non-heap buffers, or > else on demand for heap buffers at GPU page fault's IRQ handler. > > Same calculations had to be done for imported PRIME objects, since backing > storage for it might have already been allocated by the exporting driver. > > Signed-off-by: Adrián Larumbe > --- > drivers/gpu/drm/panfrost/panfrost_gem.c | 22 ++ > drivers/gpu/drm/panfrost/panfrost_gem.h | 5 + > drivers/gpu/drm/panfrost/panfrost_mmu.c | 16 +++- > 3 files changed, 38 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c > b/drivers/gpu/drm/panfrost/panfrost_gem.c > index aea16b0e4dda..c6bd1f16a6d4 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_gem.c > +++ b/drivers/gpu/drm/panfrost/panfrost_gem.c > @@ -206,6 +206,17 @@ static enum drm_gem_object_status > panfrost_gem_status(struct drm_gem_object *obj > > return res; > } > + > +size_t panfrost_gem_rss(struct drm_gem_object *obj) > +{ > + struct panfrost_gem_object *bo = to_panfrost_bo(obj); > + > + if (!bo->base.pages) > + return 0; > + > + return bo->rss_size; > +} > + > static const struct drm_gem_object_funcs panfrost_gem_funcs = { > .free = panfrost_gem_free_object, > .open = panfrost_gem_open, > @@ -218,6 +229,7 @@ static const struct drm_gem_object_funcs > panfrost_gem_funcs = { > .vunmap = drm_gem_shmem_object_vunmap, > .mmap = drm_gem_shmem_object_mmap, > .status = panfrost_gem_status, > + .rss = panfrost_gem_rss, > .vm_ops = &drm_gem_shmem_vm_ops, > }; > > @@ -274,13 +286,23 @@ panfrost_gem_prime_import_sg_table(struct drm_device > *dev, > { > struct drm_gem_object *obj; > struct panfrost_gem_object *bo; > + struct scatterlist *sgl; > + unsigned int count; > + size_t total = 0; > > obj = drm_gem_shmem_prime_import_sg_table(dev, attach, sgt); > if (IS_ERR(obj)) > return ERR_CAST(obj); > > + for_each_sgtable_dma_sg(sgt, sgl, count) { > + size_t len = sg_dma_len(sgl); > + > + total += len; > + } Why not simply have bo->rss_size = obj->size here? Not sure I see a reason to not trust dma_buf? > + > bo = to_panfrost_bo(obj); > bo->noexec = true; > + bo->rss_size = total; > > return obj; > } > diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.h > b/drivers/gpu/drm/panfrost/panfrost_gem.h > index e06f7ceb8f73..e2a7c46403c7 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_gem.h > +++ b/drivers/gpu/drm/panfrost/panfrost_gem.h > @@ -36,6 +36,11 @@ struct panfrost_gem_object { >*/ > atomic_t gpu_usecount; > > + /* > + * Object chunk size currently mapped onto physical memory > + */ > + size_t rss_size; > + > bool noexec :1; > bool is_heap:1; > bool is_purgable:1; > diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c > b/drivers/gpu/drm/panfrost/panfrost_mmu.c > index c0123d09f699..e03a5a9da06f 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c > +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c > @@ -285,17 +285,19 @@ static void panfrost_mmu_flush_range(struct > panfrost_device *pfdev, > pm_runtime_put_autosuspend(pfdev->dev); > } > > -static int mmu_map_sg(struct panfrost_device *pfdev, struct panfrost_mmu > *mmu, > +static size_t mmu_map_sg(struct panfrost_device *pfdev, struct panfrost_mmu > *mmu, > u64 iova, int prot, struct sg_table *sgt) > { > unsigned int count; > struct scatterlist *sgl; > struct io_pgtable_ops *ops = mmu->pgtbl_ops; > u64 start_iova = iova; > + size_t total = 0; > > for_each_sgtable_dma_sg(sgt, sgl, count) { > unsigned long paddr = sg_dma_address(sgl); > size_t len = sg_dma_len(sgl); > + total += len; > > dev_dbg(pfdev->dev, "map: as=%d, iova=%llx, paddr=%lx, > len=%zx", mmu->as, iova, paddr, len); > > @@ -315,7 +317,7 @@ static int mmu_map_sg(struct panfrost_device *pfdev, > struct panfrost_mmu *mmu, > > panfrost_mmu_flush_range(pfdev, mmu, start_iova, iova - start_iova); > > - return 0; > + return total; > } > > int panfrost_mmu_map(struct panfrost_gem_mapping *mapping) > @@ -326,6 +328,7 @@ int panfrost_mmu_map(struct panfrost_gem_mapping *mapping) > struct panfrost_device *pfdev = to_panfrost_device(obj->dev); > struct sg_table *sgt; > int prot = IOMMU_READ | IOMMU_WRITE; > + size_t mapped_size; > > if (WARN_ON(mapping->active)) > return 0; > @@ -337,9 +340,10 @@ int panfrost_mmu_map(struct panfrost_gem_mapping > *mapping) > if (WARN_ON(IS_ERR(sgt))) > return PTR_ERR(sgt); > > - mmu_map_
Re: [PATCH 2/2] drm/mediatek: dpi/dsi: fix possible_crtcs calculation
This won't work. On MT8195 there are two display IPs, vdosys0 and vdosys1, vdosys0 only has the main path while vdosys1 only has the external path. So you need to loop over each one in all_drm_private[j] to get the right crtc ID for MT8195. Ahh thanks, got it. -michael
Re: [PATCH v11] drm: Add initial ci/ subdirectory
On Wed, 30 Aug 2023, Maxime Ripard wrote: > On Tue, Aug 22, 2023 at 04:26:06PM +0200, Daniel Vetter wrote: >> On Fri, Aug 11, 2023 at 02:19:53PM -0300, Helen Koike wrote: >> > From: Tomeu Vizoso >> > >> > Developers can easily execute several tests on different devices >> > by just pushing their branch to their fork in a repository hosted >> > on gitlab.freedesktop.org which has an infrastructure to run jobs >> > in several runners and farms with different devices. >> > >> > There are also other automated tools that uprev dependencies, >> > monitor the infra, and so on that are already used by the Mesa >> > project, and we can reuse them too. >> > >> > Also, store expectations about what the DRM drivers are supposed >> > to pass in the IGT test suite. By storing the test expectations >> > along with the code, we can make sure both stay in sync with each >> > other so we can know when a code change breaks those expectations. >> > >> > Also, include a configuration file that points to the out-of-tree >> > CI scripts. >> > >> > This will allow all contributors to drm to reuse the infrastructure >> > already in gitlab.freedesktop.org to test the driver on several >> > generations of the hardware. >> > >> > Signed-off-by: Tomeu Vizoso >> > Signed-off-by: Helen Koike >> > Acked-by: Daniel Stone >> > Acked-by: Rob Clark >> > Tested-by: Rob Clark >> >> Ok I pushed this into a topic/drm-ci branch in drm.git and asked sfr to >> include that branch in linux-next. >> >> But also I'd like to see a lot more acks here, we should be able to at >> least pile up a bunch of (driver) maintainers from drm-misc in support of >> this. Also maybe media, at least I've heard noises that they're maybe >> interested too? Plus anyone else, the more the better. > > I'm not really convinced by that approach at all, and most of the issues > I see are shown by the follow-up series here: I'm not fully convinced either, more like "let's see". In that narrow sense, ack. I don't see harm in trying, if you're also open to backing off in case it does not pan out. > https://lore.kernel.org/dri-devel/20230825122435.316272-1-vignesh.ra...@collabora.com/ > > * We hardcode a CI farm setup into the kernel > > * We cannot trust that the code being run is actually the one being > pushed into gitlab > > * IMO, and I know we disagree here, any IGT test we enable for a given > platform should work, period. Allowing failures and flaky tests just > sweeps whatever issue is there under the rug. If the test is at > fault, we should fix the test, if the driver / kernel is at fault, > then I certainly want to know about it. At least for display, where this also depends on peripheral hardware, it's not an easy problem, really. How reliable do you need it to be? How many nines? Who is going to debug the issues that need hundreds or thousands of runs to reproduce? If a commit makes some test less reliable, how long is it going to take to even see that or pinpoint that? It's a kind of cop out, but this is not filesystems. In many cases I think we might be able to make things more robust by failing faster and failing more, but the users probably want us to plunge forward despite some errors to try to get something on screen. (Come to think of it, perhaps we should classify tests based on whether external hardware plays a role.) So I'm not so concerned about the filter lists per se, but rather about having them in kernel. BR, Jani. > > * This then leads to patches like this one: > > https://lore.kernel.org/dri-devel/20230825122435.316272-6-vignesh.ra...@collabora.com/ > > Which (and it's definitely not the author's fault) are just plain > unreadable, reproducable or auditable by anyone not heavily involved > in the CI farm operations and the platforms being tested. > > That being said, I don't have anything better to suggest than what I > already did, and it looks like I'm alone in thinking that those are > problems, so feel free to add my ack if you want to. > > Maxime -- Jani Nikula, Intel Open Source Graphics Center
Re: [PATCH v2 19/34] drm/amd/display: decouple steps for mapping CRTC degamma to DC plane
On 8/28/23 10:17, Pekka Paalanen wrote: > On Fri, 25 Aug 2023 13:29:44 -0100 > Melissa Wen wrote: > >> On 08/22, Pekka Paalanen wrote: >>> On Thu, 10 Aug 2023 15:02:59 -0100 >>> Melissa Wen wrote: >>> The next patch adds pre-blending degamma to AMD color mgmt pipeline, but pre-blending degamma caps (DPP) is currently in use to provide DRM CRTC atomic degamma or implict degamma on legacy gamma. Detach degamma usage regarging CRTC color properties to manage plane and CRTC color correction combinations. Reviewed-by: Harry Wentland Signed-off-by: Melissa Wen --- .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 59 +-- 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c index 68e9f2c62f2e..74eb02655d96 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c @@ -764,20 +764,9 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc) return 0; } -/** - * amdgpu_dm_update_plane_color_mgmt: Maps DRM color management to DC plane. - * @crtc: amdgpu_dm crtc state - * @dc_plane_state: target DC surface - * - * Update the underlying dc_stream_state's input transfer function (ITF) in - * preparation for hardware commit. The transfer function used depends on - * the preparation done on the stream for color management. - * - * Returns: - * 0 on success. -ENOMEM if mem allocation fails. - */ -int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, -struct dc_plane_state *dc_plane_state) +static int +map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc, + struct dc_plane_state *dc_plane_state) { const struct drm_color_lut *degamma_lut; enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB; @@ -800,8 +789,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, °amma_size); ASSERT(degamma_size == MAX_COLOR_LUT_ENTRIES); - dc_plane_state->in_transfer_func->type = - TF_TYPE_DISTRIBUTED_POINTS; + dc_plane_state->in_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS; /* * This case isn't fully correct, but also fairly @@ -837,7 +825,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, degamma_lut, degamma_size); if (r) return r; - } else if (crtc->cm_is_degamma_srgb) { + } else { /* * For legacy gamma support we need the regamma input * in linear space. Assume that the input is sRGB. @@ -847,8 +835,43 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, if (tf != TRANSFER_FUNCTION_SRGB && !mod_color_calculate_degamma_params(NULL, - dc_plane_state->in_transfer_func, NULL, false)) + dc_plane_state->in_transfer_func, + NULL, false)) return -ENOMEM; + } + + return 0; +} + +/** + * amdgpu_dm_update_plane_color_mgmt: Maps DRM color management to DC plane. + * @crtc: amdgpu_dm crtc state + * @dc_plane_state: target DC surface + * + * Update the underlying dc_stream_state's input transfer function (ITF) in + * preparation for hardware commit. The transfer function used depends on + * the preparation done on the stream for color management. + * + * Returns: + * 0 on success. -ENOMEM if mem allocation fails. + */ +int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, +struct dc_plane_state *dc_plane_state) +{ + bool has_crtc_cm_degamma; + int ret; + + has_crtc_cm_degamma = (crtc->cm_has_degamma || crtc->cm_is_degamma_srgb); + if (has_crtc_cm_degamma){ + /* AMD HW doesn't have post-blending degamma caps. When DRM + * CRTC atomic degamma is set, we maps it to DPP degamma block + * (pre-blending) or, on legacy gamma, we use DPP degamma to + * linearize (implicit degamma) from sRGB/BT709 according to + * the input space. >>> >>> Uhh, you can't just move degamma before blending if KMS userspace >>> wants it after blending. That would be incorrect behaviour. If you >>
Re: [PATCH v7 09/11] drm/mediatek: dp: Add support for embedded DisplayPort aux-bus
While digging through the code I realized that all the outputs and pipelines are harcoded. Doh. For all the mediatek SoCs. Looks like major restriction to me. E.g. there is also DSI and HDMI output on the mt8195. I looked at the downstream linux and there, the output is not part of the pipeline. Are you aware of any work in that direction? I'm not sure I get what output and pipelines are hardcoded that you're referring to (besides the one in the mtk-dsi/dpi driver that you already sent the patch fixing). Have a look at [1]. That main path ends with the DP_INTF0 which is the eDP output. But from what I understand that path can also use the DSI output. But that is a pattern for all the paths in that file. Looks like all supported boards in the kernel will have the output type for a given SoC/path (or maybe the mt8195 is the first one which supports different output interfaces). If you have a look at the mediatek kernel instead [2], there the last part of the path is not fixed, but there is also a .conn_routes property by which you seem to be able to choose the actual output interface. I was just curious if you know of any development for that (or similar) in the kernel. -michael And I'm not familiar with the DSI and HDMI output support on MT8195, so I can't help with that. Thanks, Nícolas [1] https://elixir.bootlin.com/linux/v6.5/source/drivers/gpu/drm/mediatek/mtk_drm_drv.c#L210 [2] https://gitlab.com/mediatek/aiot/bsp/linux/-/blob/mtk-v5.15-dev/drivers/gpu/drm/mediatek/mtk_drm_drv.c?ref_type=heads#L425
Re: [PATCH 03/12] drm/i915: Call the DDC bus i2c adapter "ddc"
On Tue, 29 Aug 2023, Ville Syrjala wrote: > From: Ville Syrjälä > > Rename the various names we've used for the DDC bus > i2c adapter ("i2c", "adapter", etc.) to just "ddc". > This differentiates it from the various other i2c > busses we might have (DSI panel stuff, DVO control bus, etc.). > > Signed-off-by: Ville Syrjälä > --- > .../gpu/drm/i915/display/intel_connector.c| 6 +-- > .../gpu/drm/i915/display/intel_connector.h| 2 +- > drivers/gpu/drm/i915/display/intel_crt.c | 32 ++-- > drivers/gpu/drm/i915/display/intel_ddi.c | 4 +- > drivers/gpu/drm/i915/display/intel_hdmi.c | 51 +-- > drivers/gpu/drm/i915/display/intel_lspcon.c | 14 ++--- > 6 files changed, 52 insertions(+), 57 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_connector.c > b/drivers/gpu/drm/i915/display/intel_connector.c > index ff3bcadebe59..c65887870ddc 100644 > --- a/drivers/gpu/drm/i915/display/intel_connector.c > +++ b/drivers/gpu/drm/i915/display/intel_connector.c > @@ -192,17 +192,17 @@ int intel_connector_update_modes(struct drm_connector > *connector, > /** > * intel_ddc_get_modes - get modelist from monitor > * @connector: DRM connector device to use > - * @adapter: i2c adapter > + * @ddc: DDC bus i2c adapter > * > * Fetch the EDID information from @connector using the DDC bus. > */ > int intel_ddc_get_modes(struct drm_connector *connector, > - struct i2c_adapter *adapter) > + struct i2c_adapter *ddc) > { > const struct drm_edid *drm_edid; > int ret; > > - drm_edid = drm_edid_read_ddc(connector, adapter); > + drm_edid = drm_edid_read_ddc(connector, ddc); > if (!drm_edid) > return 0; > > diff --git a/drivers/gpu/drm/i915/display/intel_connector.h > b/drivers/gpu/drm/i915/display/intel_connector.h > index aaf7281462dc..bafde3f11ff4 100644 > --- a/drivers/gpu/drm/i915/display/intel_connector.h > +++ b/drivers/gpu/drm/i915/display/intel_connector.h > @@ -26,7 +26,7 @@ bool intel_connector_get_hw_state(struct intel_connector > *connector); > enum pipe intel_connector_get_pipe(struct intel_connector *connector); > int intel_connector_update_modes(struct drm_connector *connector, >const struct drm_edid *drm_edid); > -int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter > *adapter); > +int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *ddc); > void intel_attach_force_audio_property(struct drm_connector *connector); > void intel_attach_broadcast_rgb_property(struct drm_connector *connector); > void intel_attach_aspect_ratio_property(struct drm_connector *connector); > diff --git a/drivers/gpu/drm/i915/display/intel_crt.c > b/drivers/gpu/drm/i915/display/intel_crt.c > index f66340b4caf0..8145511bd5c3 100644 > --- a/drivers/gpu/drm/i915/display/intel_crt.c > +++ b/drivers/gpu/drm/i915/display/intel_crt.c > @@ -610,18 +610,18 @@ static bool intel_crt_detect_hotplug(struct > drm_connector *connector) > } > > static const struct drm_edid *intel_crt_get_edid(struct drm_connector > *connector, > - struct i2c_adapter *i2c) > + struct i2c_adapter *ddc) > { > const struct drm_edid *drm_edid; > > - drm_edid = drm_edid_read_ddc(connector, i2c); > + drm_edid = drm_edid_read_ddc(connector, ddc); > > - if (!drm_edid && !intel_gmbus_is_forced_bit(i2c)) { > + if (!drm_edid && !intel_gmbus_is_forced_bit(ddc)) { > drm_dbg_kms(connector->dev, > "CRT GMBUS EDID read failed, retry using GPIO > bit-banging\n"); > - intel_gmbus_force_bit(i2c, true); > - drm_edid = drm_edid_read_ddc(connector, i2c); > - intel_gmbus_force_bit(i2c, false); > + intel_gmbus_force_bit(ddc, true); > + drm_edid = drm_edid_read_ddc(connector, ddc); > + intel_gmbus_force_bit(ddc, false); > } > > return drm_edid; > @@ -629,12 +629,12 @@ static const struct drm_edid *intel_crt_get_edid(struct > drm_connector *connector > > /* local version of intel_ddc_get_modes() to use intel_crt_get_edid() */ > static int intel_crt_ddc_get_modes(struct drm_connector *connector, > - struct i2c_adapter *adapter) > +struct i2c_adapter *ddc) > { > const struct drm_edid *drm_edid; > int ret; > > - drm_edid = intel_crt_get_edid(connector, adapter); > + drm_edid = intel_crt_get_edid(connector, ddc); > if (!drm_edid) > return 0; > > @@ -650,11 +650,11 @@ static bool intel_crt_detect_ddc(struct drm_connector > *connector) > struct intel_crt *crt = > intel_attached_crt(to_intel_connector(connector)); > struct drm_i915_private *dev_priv = to_i915(crt->base.base.dev); > const struct drm_edid *drm_edi
[-next 3/5] PCI/sysfs: Use pci_is_vga() helper
From: Sui Jingfeng Instead of accessing the PCI_CLASS_DISPLAY_VGA and pdev->class directly. The PCI_CLASS_NOT_DEFINED_VGA is defined to provide backward compatibility for devices that were built before the class code field was defined. It should be visiable via sysfs(boot_vga) as the normal VGA-compatible devices. Cc: "Maciej W. Rozycki" Signed-off-by: Sui Jingfeng --- drivers/pci/pci-sysfs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index d9eede2dbc0e..522708938563 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -1552,10 +1552,10 @@ static umode_t pci_dev_attrs_are_visible(struct kobject *kobj, struct pci_dev *pdev = to_pci_dev(dev); if (a == &dev_attr_boot_vga.attr) - if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA) - return 0; + if (pci_is_vga(pdev)) + return a->mode; - return a->mode; + return 0; } static struct attribute *pci_dev_hp_attrs[] = { -- 2.34.1
[-next 5/5] drm/qxl: Switch to pci_is_vga()
From: Sui Jingfeng Should be no functional change, just for cleanup purpose. Cc: Dave Airlie Cc: Gerd Hoffmann Cc: David Airlie Cc: Daniel Vetter Signed-off-by: Sui Jingfeng --- drivers/gpu/drm/qxl/qxl_drv.c | 11 +++ 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index a3b83f89e061..08586bd2448f 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c @@ -68,11 +68,6 @@ module_param_named(num_heads, qxl_num_crtc, int, 0400); static struct drm_driver qxl_driver; static struct pci_driver qxl_pci_driver; -static bool is_vga(struct pci_dev *pdev) -{ - return pdev->class == PCI_CLASS_DISPLAY_VGA << 8; -} - static int qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -100,7 +95,7 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) goto disable_pci; - if (is_vga(pdev) && pdev->revision < 5) { + if (pci_is_vga(pdev) && pdev->revision < 5) { ret = vga_get_interruptible(pdev, VGA_RSRC_LEGACY_IO); if (ret) { DRM_ERROR("can't get legacy vga ioports\n"); @@ -131,7 +126,7 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) unload: qxl_device_fini(qdev); put_vga: - if (is_vga(pdev) && pdev->revision < 5) + if (pci_is_vga(pdev) && pdev->revision < 5) vga_put(pdev, VGA_RSRC_LEGACY_IO); disable_pci: pci_disable_device(pdev); @@ -159,7 +154,7 @@ qxl_pci_remove(struct pci_dev *pdev) drm_dev_unregister(dev); drm_atomic_helper_shutdown(dev); - if (is_vga(pdev) && pdev->revision < 5) + if (pci_is_vga(pdev) && pdev->revision < 5) vga_put(pdev, VGA_RSRC_LEGACY_IO); } -- 2.34.1
[-next 4/5] drm/virgpu: Switch to pci_is_vga()
From: Sui Jingfeng Should be no functional change, just for cleanup purpose. Cc: David Airlie Cc: Gerd Hoffmann Cc: Gurchetan Singh Cc: Chia-I Wu Cc: Daniel Vetter Signed-off-by: Sui Jingfeng --- drivers/gpu/drm/virtio/virtgpu_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index add075681e18..3a368304475a 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -51,7 +51,7 @@ static int virtio_gpu_pci_quirk(struct drm_device *dev) { struct pci_dev *pdev = to_pci_dev(dev->dev); const char *pname = dev_name(&pdev->dev); - bool vga = (pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA; + bool vga = pci_is_vga(pdev); int ret; DRM_INFO("pci: %s detected at %s\n", -- 2.34.1
[-next 1/5] PCI: Add the pci_is_vga() helper
From: Sui Jingfeng The PCI code and ID assignment specification defined four types of display controllers for the display base class(03h), and the devices with 0x00h sub-class code are VGA devices. VGA devices with programming interface 0x00 is VGA-compatible, VGA devices with programming interface 0x01 are 8514-compatible controllers. Besides, PCI_CLASS_NOT_DEFINED_VGA is defined to provide backward compatibility for devices that were built before the class code field was defined. Hence, introduce the pci_is_vga() helper, let it handle the details for us. It returns true if the PCI(e) device being tested belongs to the VGA devices category. Cc: "Maciej W. Rozycki" Signed-off-by: Sui Jingfeng --- include/linux/pci.h | 27 +++ 1 file changed, 27 insertions(+) diff --git a/include/linux/pci.h b/include/linux/pci.h index cf6e0b057752..ace727001911 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -713,6 +713,33 @@ static inline bool pci_is_bridge(struct pci_dev *dev) dev->hdr_type == PCI_HEADER_TYPE_CARDBUS; } +/** + * The PCI code and ID assignment specification defined four types of + * display controllers for the display base class(03h), and the devices + * with 0x00h sub-class code are VGA devices. VGA devices with programming + * interface 0x00 is VGA-compatible, VGA devices with programming interface + * 0x01 are 8514-compatible controllers. Besides, PCI_CLASS_NOT_DEFINED_VGA + * is defined to provide backward compatibility for devices that were built + * before the class code field was defined. This means that it belong to the + * VGA devices category also. + * + * Returns: + * true if the PCI device is a VGA device, false otherwise. + */ +static inline bool pci_is_vga(struct pci_dev *pdev) +{ + if (!pdev) + return false; + + if ((pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA) + return true; + + if ((pdev->class >> 8) == PCI_CLASS_NOT_DEFINED_VGA) + return true; + + return false; +} + #define for_each_pci_bridge(dev, bus) \ list_for_each_entry(dev, &bus->devices, bus_list) \ if (!pci_is_bridge(dev)) {} else -- 2.34.1
[-next 0/5] Add the pci_is_vga() helper and use it
From: Sui Jingfeng The PCI code and ID assignment specification defined four types of display controllers for the display base class(03h), and the devices with 0x00h sub-class code are VGA devices. VGA devices with programming interface 0x00 is VGA-compatible, VGA devices with programming interface 0x01 are 8514-compatible controllers. Besides, PCI_CLASS_NOT_DEFINED_VGA is defined to provide backward compatibility for devices that were built before the class code field was defined. Thus, PCI(e) device with the PCI_CLASS_NOT_DEFINED_VGA class code should also be handled as the normal VGA-compatible devices. Compared with the "if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA)" code, the newly implemented pci_is_vga() is shorter and straightforward. So it is more easy to use. It is designed as a inline function, the more common case "if ((pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA))" is put before the less common case "if ((pdev->class >> 8) == PCI_CLASS_NOT_DEFINED_VGA)", so there should no performance penalty. Sui Jingfeng (5): PCI: Add the pci_is_vga() helper PCI/VGA: Deal with VGA devices PCI/sysfs: Use pci_is_vga() helper drm/virgpu: Switch to pci_is_vga() drm/qxl: Switch to pci_is_vga() drivers/gpu/drm/qxl/qxl_drv.c| 11 +++ drivers/gpu/drm/virtio/virtgpu_drv.c | 2 +- drivers/pci/pci-sysfs.c | 6 +++--- drivers/pci/vgaarb.c | 19 +-- include/linux/pci.h | 27 +++ 5 files changed, 43 insertions(+), 22 deletions(-) base-commit: 43cc31da9146f9ce60e4a03d96ef0807c2cdac94 -- 2.34.1
[-next 2/5] PCI/VGA: Deal with VGA devices
From: Sui Jingfeng VGAARB only cares about PCI(e) VGA devices, thus filtering out unqualified devices as early as possible. This also means that deleting a non-VGA device snooped won't unnecessarily call into vga_arbiter_del_pci_device() function. By using the newly implemented pci_is_vga(), PCI(e) with PCI_CLASS_NOT_DEFINED_VGA class code will also be handled. Cc: "Maciej W. Rozycki" Reviewed-by: Mario Limonciello Signed-off-by: Sui Jingfeng --- drivers/pci/vgaarb.c | 19 +-- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c index 5e6b1eb54c64..ef8fe685de67 100644 --- a/drivers/pci/vgaarb.c +++ b/drivers/pci/vgaarb.c @@ -764,10 +764,6 @@ static bool vga_arbiter_add_pci_device(struct pci_dev *pdev) struct pci_dev *bridge; u16 cmd; - /* Only deal with VGA class devices */ - if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA) - return false; - /* Allocate structure */ vgadev = kzalloc(sizeof(struct vga_device), GFP_KERNEL); if (vgadev == NULL) { @@ -1503,6 +1499,9 @@ static int pci_notify(struct notifier_block *nb, unsigned long action, vgaarb_dbg(dev, "%s\n", __func__); + if (!pci_is_vga(pdev)) + return 0; + /* * For now, we're only interested in devices added and removed. * I didn't test this thing here, so someone needs to double check @@ -1537,8 +1536,8 @@ static struct miscdevice vga_arb_device = { static int __init vga_arb_device_init(void) { + struct pci_dev *pdev = NULL; int rc; - struct pci_dev *pdev; rc = misc_register(&vga_arb_device); if (rc < 0) @@ -1547,11 +1546,11 @@ static int __init vga_arb_device_init(void) bus_register_notifier(&pci_bus_type, &pci_notifier); /* Add all VGA class PCI devices by default */ - pdev = NULL; - while ((pdev = - pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, - PCI_ANY_ID, pdev)) != NULL) - vga_arbiter_add_pci_device(pdev); + do { + pdev = pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, pdev); + if (pci_is_vga(pdev)) + vga_arbiter_add_pci_device(pdev); + } while (pdev); pr_info("loaded\n"); return rc; -- 2.34.1
Re: [RFC PATCH] kunit: Fix test log size limit too low for some tests
On Wednesday, 30 August 2023 11:23:43 CEST David Gow wrote: > On Wed, 30 Aug 2023 at 15:55, Janusz Krzysztofik > wrote: > > > > Now we have memory space available to a kunit test case log exposed via > > debugfs limited to 2048 bytes, while some parametrized test cases, e.g., > > drm_framebuffer.drm_test_framebuffer_create, need more. For this reason, > > debugfs results from affected test cases get truncated silently, and > > external tools that rely on parsing of debugfs results can fail. > > > > Increase kunit test case log size limit to 4096 bytes. > > > > Signed-off-by: Janusz Krzysztofik > > --- > > There's a patch series we're hoping to take for 6.7 which allows the > log to grow to fit whatever's written into it, which should make this > patch obsolete: > https://lore.kernel.org/linux-kselftest/20230828104111.2394344-1...@opensource.cirrus.com/T/ > > Would that work for you? Yeah, that's going to work perfectly for us, thank you. Janusz > > -- David > > > include/kunit/test.h | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/include/kunit/test.h b/include/kunit/test.h > > index d33114097d0d0..d20eb1884edfa 100644 > > --- a/include/kunit/test.h > > +++ b/include/kunit/test.h > > @@ -34,7 +34,7 @@ DECLARE_STATIC_KEY_FALSE(kunit_running); > > struct kunit; > > > > /* Size of log associated with test. */ > > -#define KUNIT_LOG_SIZE 2048 > > +#define KUNIT_LOG_SIZE 4096 > > > > /* Maximum size of parameter description string. */ > > #define KUNIT_PARAM_DESC_SIZE 128 > > -- > > 2.41.0 > > >
Re: [PATCH v11] drm: Add initial ci/ subdirectory
On Wed, Aug 30, 2023 at 01:58:31PM +0300, Jani Nikula wrote: > On Wed, 30 Aug 2023, Maxime Ripard wrote: > > On Tue, Aug 22, 2023 at 04:26:06PM +0200, Daniel Vetter wrote: > >> On Fri, Aug 11, 2023 at 02:19:53PM -0300, Helen Koike wrote: > >> > From: Tomeu Vizoso > >> > > >> > Developers can easily execute several tests on different devices > >> > by just pushing their branch to their fork in a repository hosted > >> > on gitlab.freedesktop.org which has an infrastructure to run jobs > >> > in several runners and farms with different devices. > >> > > >> > There are also other automated tools that uprev dependencies, > >> > monitor the infra, and so on that are already used by the Mesa > >> > project, and we can reuse them too. > >> > > >> > Also, store expectations about what the DRM drivers are supposed > >> > to pass in the IGT test suite. By storing the test expectations > >> > along with the code, we can make sure both stay in sync with each > >> > other so we can know when a code change breaks those expectations. > >> > > >> > Also, include a configuration file that points to the out-of-tree > >> > CI scripts. > >> > > >> > This will allow all contributors to drm to reuse the infrastructure > >> > already in gitlab.freedesktop.org to test the driver on several > >> > generations of the hardware. > >> > > >> > Signed-off-by: Tomeu Vizoso > >> > Signed-off-by: Helen Koike > >> > Acked-by: Daniel Stone > >> > Acked-by: Rob Clark > >> > Tested-by: Rob Clark > >> > >> Ok I pushed this into a topic/drm-ci branch in drm.git and asked sfr to > >> include that branch in linux-next. > >> > >> But also I'd like to see a lot more acks here, we should be able to at > >> least pile up a bunch of (driver) maintainers from drm-misc in support of > >> this. Also maybe media, at least I've heard noises that they're maybe > >> interested too? Plus anyone else, the more the better. > > > > I'm not really convinced by that approach at all, and most of the issues > > I see are shown by the follow-up series here: > > I'm not fully convinced either, more like "let's see". In that narrow > sense, ack. I don't see harm in trying, if you're also open to backing > off in case it does not pan out. > > > https://lore.kernel.org/dri-devel/20230825122435.316272-1-vignesh.ra...@collabora.com/ > > > > * We hardcode a CI farm setup into the kernel > > > > * We cannot trust that the code being run is actually the one being > > pushed into gitlab > > > > * IMO, and I know we disagree here, any IGT test we enable for a given > > platform should work, period. Allowing failures and flaky tests just > > sweeps whatever issue is there under the rug. If the test is at > > fault, we should fix the test, if the driver / kernel is at fault, > > then I certainly want to know about it. > > At least for display, where this also depends on peripheral hardware, > it's not an easy problem, really. Aside from the Chamelium tests, which tests actually rely on peripheral hardware? On EDID and hotplug, sure, but that can easily be set up from the userspace, or something like https://www.lindy-international.com/HDMI-2-0-EDID-Emulator.htm?websale8=ld0101.ld021102&pi=32115 > How reliable do you need it to be? How many nines? Who is going to > debug the issues that need hundreds or thousands of runs to reproduce? > If a commit makes some test less reliable, how long is it going to > take to even see that or pinpoint that? I mean, that's also true for failures or success then. How many times do you need a test to run properly to qualify it as a meaningful test? How do you know that it's not a flaky test? Ultimately, it's about trust. If, for a given test that just failed, I can't be certain that it's because of the branch I just submitted, I will just ignore the tests results after a while. This is already what plagues kernelci, and we should do better. And I'm sorry, but if some part of the kernel or driver just isn't reliable, then we shouldn't claim it is (except for all the times it isn't). If no-one has the time to look into it, fine, but flagging it under a flaky test doesn't help anyone. Like, from that patch, how can I know what is the issue with kms_hdmi_inject@inject-4k or kms_addfb_basic@addfb25-bad-modifier on mt8173. I certainly can't. And neither of those have anything to do with peripheral hardware. Maxime signature.asc Description: PGP signature
Re: [Intel-gfx] [PATCH 01/12] drm: Reorder drm_sysfs_connector_remove() vs. drm_debugfs_connector_remove()
On Tue, 29 Aug 2023, Ville Syrjala wrote: > From: Ville Syrjälä > > Use the standard onion peeling approach and call > drm_debugfs_connector_remove() and > drm_sysfs_connector_remove() in the reverse order in > drm_connector_unregister() than what we called their > add counterpartse in drm_connector_register(). > > The error unwiding in drm_connector_register() is > already doing this the correct way around. > > Signed-off-by: Ville Syrjälä Reviewed-by: Jani Nikula > --- > drivers/gpu/drm/drm_connector.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c > index c44d5bcf1284..988996cf6da5 100644 > --- a/drivers/gpu/drm/drm_connector.c > +++ b/drivers/gpu/drm/drm_connector.c > @@ -684,8 +684,8 @@ void drm_connector_unregister(struct drm_connector > *connector) > if (connector->funcs->early_unregister) > connector->funcs->early_unregister(connector); > > - drm_sysfs_connector_remove(connector); > drm_debugfs_connector_remove(connector); > + drm_sysfs_connector_remove(connector); > > connector->registration_state = DRM_CONNECTOR_UNREGISTERED; > mutex_unlock(&connector->mutex); -- Jani Nikula, Intel Open Source Graphics Center
Re: [PATCH 02/12] drm/sysfs: Register "ddc" symlink later
On Tue, 29 Aug 2023, Ville Syrjala wrote: > From: Ville Syrjälä > > Currently drm_sysfs_connector_add() attempts to register > the "ddc" symlink (based one connector->ddc) before the > driver's .early_register() hook has been called. That is > too early for i915 which only fully registers the aux ch > and associated i2c bus from said hook (to prevent half > initialized stuff getting exposed to userspace). This > causes my attempt at using drm_connector_init_with_ddc() > to fail, and the entire connector disappears from sysfs > on account of sysfs_create_link() failing. > > To fix that split the sysfs symlink stuff into separate > functions (drm_sysfs_connector_add_late() and > drm_sysfs_connector_remove_early()) which are called > on the opposite side of the .later_register() and > .early_unregister() hooks. > > Cc: Andrzej Pietrasiewicz > Cc: Daniel Vetter > Cc: Andrzej Hajda > Cc: Emil Velikov > Cc: Sam Ravnborg > Cc: Neil Armstrong > Signed-off-by: Ville Syrjälä Reviewed-by: Jani Nikula > --- > drivers/gpu/drm/drm_connector.c | 9 + > drivers/gpu/drm/drm_internal.h | 2 ++ > drivers/gpu/drm/drm_sysfs.c | 22 +++--- > 3 files changed, 26 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c > index 988996cf6da5..9d4c7b0c5c05 100644 > --- a/drivers/gpu/drm/drm_connector.c > +++ b/drivers/gpu/drm/drm_connector.c > @@ -631,6 +631,10 @@ int drm_connector_register(struct drm_connector > *connector) > goto err_debugfs; > } > > + ret = drm_sysfs_connector_add_late(connector); > + if (ret) > + goto err_late_register; > + > drm_mode_object_register(connector->dev, &connector->base); > > connector->registration_state = DRM_CONNECTOR_REGISTERED; > @@ -647,6 +651,9 @@ int drm_connector_register(struct drm_connector > *connector) > mutex_unlock(&connector_list_lock); > goto unlock; > > +err_late_register: > + if (connector->funcs->early_unregister) > + connector->funcs->early_unregister(connector); > err_debugfs: > drm_debugfs_connector_remove(connector); > drm_sysfs_connector_remove(connector); > @@ -681,6 +688,8 @@ void drm_connector_unregister(struct drm_connector > *connector) > connector->privacy_screen, > &connector->privacy_screen_notifier); > > + drm_sysfs_connector_remove_early(connector); > + > if (connector->funcs->early_unregister) > connector->funcs->early_unregister(connector); > > diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h > index ba12acd55139..4053cf8105ce 100644 > --- a/drivers/gpu/drm/drm_internal.h > +++ b/drivers/gpu/drm/drm_internal.h > @@ -153,6 +153,8 @@ int drm_sysfs_init(void); > void drm_sysfs_destroy(void); > struct device *drm_sysfs_minor_alloc(struct drm_minor *minor); > int drm_sysfs_connector_add(struct drm_connector *connector); > +int drm_sysfs_connector_add_late(struct drm_connector *connector); > +void drm_sysfs_connector_remove_early(struct drm_connector *connector); > void drm_sysfs_connector_remove(struct drm_connector *connector); > > void drm_sysfs_lease_event(struct drm_device *dev); > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c > index b169b3e44a92..a953f69a34b6 100644 > --- a/drivers/gpu/drm/drm_sysfs.c > +++ b/drivers/gpu/drm/drm_sysfs.c > @@ -400,10 +400,6 @@ int drm_sysfs_connector_add(struct drm_connector > *connector) > drm_err(dev, "failed to add component to create link to > typec connector\n"); > } > > - if (connector->ddc) > - return sysfs_create_link(&connector->kdev->kobj, > - &connector->ddc->dev.kobj, "ddc"); > - > return 0; > > err_free: > @@ -411,14 +407,26 @@ int drm_sysfs_connector_add(struct drm_connector > *connector) > return r; > } > > +int drm_sysfs_connector_add_late(struct drm_connector *connector) > +{ > + if (connector->ddc) > + return sysfs_create_link(&connector->kdev->kobj, > + &connector->ddc->dev.kobj, "ddc"); > + > + return 0; > +} > + > +void drm_sysfs_connector_remove_early(struct drm_connector *connector) > +{ > + if (connector->ddc) > + sysfs_remove_link(&connector->kdev->kobj, "ddc"); > +} > + > void drm_sysfs_connector_remove(struct drm_connector *connector) > { > if (!connector->kdev) > return; > > - if (connector->ddc) > - sysfs_remove_link(&connector->kdev->kobj, "ddc"); > - > if (dev_fwnode(connector->kdev)) > component_del(connector->kdev, &typec_connector_ops); -- Jani Nikula, Intel Open Source Graphics Center
Re: [Intel-gfx] [1/2] drm/display/dp: Assume 8 bpc support when DSC is supported
On Wed, 30 Aug 2023, "Lisovskiy, Stanislav" wrote: > On Thu, Aug 24, 2023 at 06:21:20PM +0530, Ankit Nautiyal wrote: >> As per DP v1.4, a DP DSC Sink device shall support 8bpc in DPCD 6Ah. >> Apparently some panels that do support DSC, are not setting the bit for >> 8bpc. >> >> So always assume 8bpc support by DSC decoder, when DSC is claimed to be >> supported. >> >> v2: Use helper to get check dsc support. (Ankit) >> v3: Fix styling and other typos. (Jani) >> >> Signed-off-by: Ankit Nautiyal > > Reviewed-by: Stanislav Lisovskiy Pushed both to drm-intel-next, with Maxime's ack, thanks for the patches and review. BR, Jani. > >> --- >> drivers/gpu/drm/display/drm_dp_helper.c | 8 ++-- >> 1 file changed, 6 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/gpu/drm/display/drm_dp_helper.c >> b/drivers/gpu/drm/display/drm_dp_helper.c >> index e6a78fd32380..8a1b64c57dfd 100644 >> --- a/drivers/gpu/drm/display/drm_dp_helper.c >> +++ b/drivers/gpu/drm/display/drm_dp_helper.c >> @@ -2449,12 +2449,16 @@ int drm_dp_dsc_sink_supported_input_bpcs(const u8 >> dsc_dpcd[DP_DSC_RECEIVER_CAP_S >> int num_bpc = 0; >> u8 color_depth = dsc_dpcd[DP_DSC_DEC_COLOR_DEPTH_CAP - DP_DSC_SUPPORT]; >> >> +if (!drm_dp_sink_supports_dsc(dsc_dpcd)) >> +return 0; >> + >> if (color_depth & DP_DSC_12_BPC) >> dsc_bpc[num_bpc++] = 12; >> if (color_depth & DP_DSC_10_BPC) >> dsc_bpc[num_bpc++] = 10; >> -if (color_depth & DP_DSC_8_BPC) >> -dsc_bpc[num_bpc++] = 8; >> + >> +/* A DP DSC Sink device shall support 8 bpc. */ >> +dsc_bpc[num_bpc++] = 8; >> >> return num_bpc; >> } -- Jani Nikula, Intel Open Source Graphics Center
Re: [Intel-gfx] [PATCH 2/2] drivers/drm/i915: Honor limits->max_bpp while computing DSC max input bpp
On Thu, 24 Aug 2023, Ankit Nautiyal wrote: > Edid specific BPC constraints are stored in limits->max_bpp. Honor these > limits while computing the input bpp for DSC. > > v2: Use int instead of u8 for computations. (Jani) > Add closes tag. (Ankit) > > Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/9161 > Signed-off-by: Ankit Nautiyal > Reviewed-by: Stanislav Lisovskiy > --- > drivers/gpu/drm/i915/display/intel_dp.c | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c > b/drivers/gpu/drm/i915/display/intel_dp.c > index 7067ee3a4bd3..8f3dc79089ea 100644 > --- a/drivers/gpu/drm/i915/display/intel_dp.c > +++ b/drivers/gpu/drm/i915/display/intel_dp.c > @@ -2061,9 +2061,10 @@ static int intel_edp_dsc_compute_pipe_bpp(struct > intel_dp *intel_dp, > if (forced_bpp) { > pipe_bpp = forced_bpp; > } else { > + int max_bpc = min(limits->max_bpp / 3, > (int)conn_state->max_requested_bpc); Hmh, only noticed after pushing, there's min_t() for when the types differ. BR, Jani. > + > /* For eDP use max bpp that can be supported with DSC. */ > - pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, > - > conn_state->max_requested_bpc); > + pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, max_bpc); > if (!is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, > pipe_bpp)) { > drm_dbg_kms(&i915->drm, > "Computed BPC is not in DSC BPC limits\n"); -- Jani Nikula, Intel Open Source Graphics Center
Re: [Intel-gfx] [PATCH 03/12] drm/i915: Call the DDC bus i2c adapter "ddc"
On Wed, 30 Aug 2023, Jani Nikula wrote: > On Tue, 29 Aug 2023, Ville Syrjala wrote: >> From: Ville Syrjälä >> @@ -2452,24 +2447,24 @@ intel_hdmi_set_edid(struct drm_connector *connector) >> { >> struct drm_i915_private *dev_priv = to_i915(connector->dev); >> struct intel_hdmi *intel_hdmi = >> intel_attached_hdmi(to_intel_connector(connector)); >> +struct i2c_adapter *ddc = intel_gmbus_get_adapter(dev_priv, >> intel_hdmi->ddc_bus); >> intel_wakeref_t wakeref; >> const struct drm_edid *drm_edid; >> const struct edid *edid; >> bool connected = false; >> -struct i2c_adapter *i2c; >> >> wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); >> >> -i2c = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus); >> +edid = drm_get_edid(connector, ddc); > > Must be a rebase fail. With this + line dropped, everything else is Reviewed-by: Jani Nikula > > BR, > Jani. > >> >> -drm_edid = drm_edid_read_ddc(connector, i2c); >> +drm_edid = drm_edid_read_ddc(connector, ddc); >> >> -if (!drm_edid && !intel_gmbus_is_forced_bit(i2c)) { >> +if (!drm_edid && !intel_gmbus_is_forced_bit(ddc)) { >> drm_dbg_kms(&dev_priv->drm, >> "HDMI GMBUS EDID read failed, retry using GPIO >> bit-banging\n"); >> -intel_gmbus_force_bit(i2c, true); >> -drm_edid = drm_edid_read_ddc(connector, i2c); >> -intel_gmbus_force_bit(i2c, false); >> +intel_gmbus_force_bit(ddc, true); >> +drm_edid = drm_edid_read_ddc(connector, ddc); >> +intel_gmbus_force_bit(ddc, false); >> } >> >> /* Below we depend on display info having been updated */ >> @@ -2561,8 +2556,8 @@ intel_hdmi_get_i2c_adapter(struct drm_connector >> *connector) >> static void intel_hdmi_create_i2c_symlink(struct drm_connector *connector) >> { >> struct drm_i915_private *i915 = to_i915(connector->dev); >> -struct i2c_adapter *adapter = intel_hdmi_get_i2c_adapter(connector); >> -struct kobject *i2c_kobj = &adapter->dev.kobj; >> +struct i2c_adapter *ddc = intel_hdmi_get_i2c_adapter(connector); >> +struct kobject *i2c_kobj = &ddc->dev.kobj; >> struct kobject *connector_kobj = &connector->kdev->kobj; >> int ret; >> >> @@ -2573,8 +2568,8 @@ static void intel_hdmi_create_i2c_symlink(struct >> drm_connector *connector) >> >> static void intel_hdmi_remove_i2c_symlink(struct drm_connector *connector) >> { >> -struct i2c_adapter *adapter = intel_hdmi_get_i2c_adapter(connector); >> -struct kobject *i2c_kobj = &adapter->dev.kobj; >> +struct i2c_adapter *ddc = intel_hdmi_get_i2c_adapter(connector); >> +struct kobject *i2c_kobj = &ddc->dev.kobj; >> struct kobject *connector_kobj = &connector->kdev->kobj; >> >> sysfs_remove_link(connector_kobj, i2c_kobj->name); >> diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c >> b/drivers/gpu/drm/i915/display/intel_lspcon.c >> index bb3b5355a0d9..152a22a8ffd2 100644 >> --- a/drivers/gpu/drm/i915/display/intel_lspcon.c >> +++ b/drivers/gpu/drm/i915/display/intel_lspcon.c >> @@ -144,9 +144,9 @@ static enum drm_lspcon_mode >> lspcon_get_current_mode(struct intel_lspcon *lspcon) >> struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon); >> struct drm_i915_private *i915 = dp_to_i915(intel_dp); >> enum drm_lspcon_mode current_mode; >> -struct i2c_adapter *adapter = &intel_dp->aux.ddc; >> +struct i2c_adapter *ddc = &intel_dp->aux.ddc; >> >> -if (drm_lspcon_get_mode(intel_dp->aux.drm_dev, adapter, ¤t_mode)) >> { >> +if (drm_lspcon_get_mode(intel_dp->aux.drm_dev, ddc, ¤t_mode)) { >> drm_dbg_kms(&i915->drm, "Error reading LSPCON mode\n"); >> return DRM_LSPCON_MODE_INVALID; >> } >> @@ -185,9 +185,9 @@ static int lspcon_change_mode(struct intel_lspcon >> *lspcon, >> struct drm_i915_private *i915 = dp_to_i915(intel_dp); >> int err; >> enum drm_lspcon_mode current_mode; >> -struct i2c_adapter *adapter = &intel_dp->aux.ddc; >> +struct i2c_adapter *ddc = &intel_dp->aux.ddc; >> >> -err = drm_lspcon_get_mode(intel_dp->aux.drm_dev, adapter, >> ¤t_mode); >> +err = drm_lspcon_get_mode(intel_dp->aux.drm_dev, ddc, ¤t_mode); >> if (err) { >> drm_err(&i915->drm, "Error reading LSPCON mode\n"); >> return err; >> @@ -198,7 +198,7 @@ static int lspcon_change_mode(struct intel_lspcon >> *lspcon, >> return 0; >> } >> >> -err = drm_lspcon_set_mode(intel_dp->aux.drm_dev, adapter, mode); >> +err = drm_lspcon_set_mode(intel_dp->aux.drm_dev, ddc, mode); >> if (err < 0) { >> drm_err(&i915->drm, "LSPCON mode change failed\n"); >> return err; >> @@ -233,7 +233,7 @@ static bool lspcon_probe(struct intel_lspcon *lspcon) >> enum drm_dp_dual_mode_type adaptor_type; >> struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon); >>
Re: [Intel-gfx] [PATCH 04/12] drm/i915/lvds: Populate connector->ddc
On Tue, 29 Aug 2023, Ville Syrjala wrote: > From: Ville Syrjälä > > Populate connector->ddc, and thus create the "ddc" symlink > in sysfs for the LVDS port. > > Signed-off-by: Ville Syrjälä Reviewed-by: Jani Nikula > --- > drivers/gpu/drm/i915/display/intel_lvds.c | 23 +++ > 1 file changed, 11 insertions(+), 12 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c > b/drivers/gpu/drm/i915/display/intel_lvds.c > index 3ace56979b70..2306e133e3f6 100644 > --- a/drivers/gpu/drm/i915/display/intel_lvds.c > +++ b/drivers/gpu/drm/i915/display/intel_lvds.c > @@ -837,7 +837,7 @@ void intel_lvds_init(struct drm_i915_private *i915) > struct intel_encoder *encoder; > i915_reg_t lvds_reg; > u32 lvds; > - u8 pin; > + u8 ddc_pin; > > /* Skip init on machines we know falsely report LVDS */ > if (dmi_check_system(intel_no_lvds)) { > @@ -864,8 +864,8 @@ void intel_lvds_init(struct drm_i915_private *i915) > return; > } > > - pin = GMBUS_PIN_PANEL; > - if (!intel_bios_is_lvds_present(i915, &pin)) { > + ddc_pin = GMBUS_PIN_PANEL; > + if (!intel_bios_is_lvds_present(i915, &ddc_pin)) { > if ((lvds & LVDS_PORT_EN) == 0) { > drm_dbg_kms(&i915->drm, > "LVDS is not present in VBT\n"); > @@ -888,8 +888,10 @@ void intel_lvds_init(struct drm_i915_private *i915) > lvds_encoder->attached_connector = connector; > encoder = &lvds_encoder->base; > > - drm_connector_init(&i915->drm, &connector->base, > &intel_lvds_connector_funcs, > -DRM_MODE_CONNECTOR_LVDS); > + drm_connector_init_with_ddc(&i915->drm, &connector->base, > + &intel_lvds_connector_funcs, > + DRM_MODE_CONNECTOR_LVDS, > + intel_gmbus_get_adapter(i915, ddc_pin)); > > drm_encoder_init(&i915->drm, &encoder->base, &intel_lvds_enc_funcs, >DRM_MODE_ENCODER_LVDS, "LVDS"); > @@ -943,13 +945,10 @@ void intel_lvds_init(struct drm_i915_private *i915) >* preferred mode is the right one. >*/ > mutex_lock(&i915->drm.mode_config.mutex); > - if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC) { > - drm_edid = drm_edid_read_switcheroo(&connector->base, > - > intel_gmbus_get_adapter(i915, pin)); > - } else { > - drm_edid = drm_edid_read_ddc(&connector->base, > - intel_gmbus_get_adapter(i915, > pin)); > - } > + if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC) > + drm_edid = drm_edid_read_switcheroo(&connector->base, > connector->base.ddc); > + else > + drm_edid = drm_edid_read_ddc(&connector->base, > connector->base.ddc); > if (drm_edid) { > if (drm_edid_connector_update(&connector->base, drm_edid) || > !drm_edid_connector_add_modes(&connector->base)) { -- Jani Nikula, Intel Open Source Graphics Center
Re: [Intel-gfx] [PATCH 05/12] drm/i915/crt: Populate connector->ddc
On Tue, 29 Aug 2023, Ville Syrjala wrote: > From: Ville Syrjälä > > Populate connector->ddc, and thus create the "ddc" symlink > in sysfs for analog VGA connectors. > > As a bonus we can replace a bunch of intel_gmbus_get_adapter() > lookups with just the connector->ddc pointer. Sadly one extra > lookup still remains due to the g4x DVI-I shenanigans. We could > perhaps consider borrowing the ddc proxy idea from SDVO to deal > with that in a perhaps nicer way, but can't really be bothered > right now at least. Also not sure exposing such a dual ddc bus > to userspace would be quite wise. > > Signed-off-by: Ville Syrjälä Reviewed-by: Jani Nikula > --- > drivers/gpu/drm/i915/display/intel_crt.c | 16 +--- > 1 file changed, 9 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_crt.c > b/drivers/gpu/drm/i915/display/intel_crt.c > index 8145511bd5c3..ea3908fd2505 100644 > --- a/drivers/gpu/drm/i915/display/intel_crt.c > +++ b/drivers/gpu/drm/i915/display/intel_crt.c > @@ -650,11 +650,9 @@ static bool intel_crt_detect_ddc(struct drm_connector > *connector) > struct intel_crt *crt = > intel_attached_crt(to_intel_connector(connector)); > struct drm_i915_private *dev_priv = to_i915(crt->base.base.dev); > const struct drm_edid *drm_edid; > - struct i2c_adapter *ddc; > bool ret = false; > > - ddc = intel_gmbus_get_adapter(dev_priv, > dev_priv->display.vbt.crt_ddc_pin); > - drm_edid = intel_crt_get_edid(connector, ddc); > + drm_edid = intel_crt_get_edid(connector, connector->ddc); > > if (drm_edid) { > const struct edid *edid = drm_edid_raw(drm_edid); > @@ -923,8 +921,7 @@ static int intel_crt_get_modes(struct drm_connector > *connector) > wakeref = intel_display_power_get(dev_priv, > intel_encoder->power_domain); > > - ddc = intel_gmbus_get_adapter(dev_priv, > dev_priv->display.vbt.crt_ddc_pin); > - ret = intel_crt_ddc_get_modes(connector, ddc); > + ret = intel_crt_ddc_get_modes(connector, connector->ddc); > if (ret || !IS_G4X(dev_priv)) > goto out; > > @@ -988,6 +985,7 @@ void intel_crt_init(struct drm_i915_private *dev_priv) > struct intel_crt *crt; > struct intel_connector *intel_connector; > i915_reg_t adpa_reg; > + u8 ddc_pin; > u32 adpa; > > if (HAS_PCH_SPLIT(dev_priv)) > @@ -1024,10 +1022,14 @@ void intel_crt_init(struct drm_i915_private *dev_priv) > return; > } > > + ddc_pin = dev_priv->display.vbt.crt_ddc_pin; > + > connector = &intel_connector->base; > crt->connector = intel_connector; > - drm_connector_init(&dev_priv->drm, &intel_connector->base, > -&intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); > + drm_connector_init_with_ddc(&dev_priv->drm, connector, > + &intel_crt_connector_funcs, > + DRM_MODE_CONNECTOR_VGA, > + intel_gmbus_get_adapter(dev_priv, ddc_pin)); > > drm_encoder_init(&dev_priv->drm, &crt->base.base, &intel_crt_enc_funcs, >DRM_MODE_ENCODER_DAC, "CRT"); -- Jani Nikula, Intel Open Source Graphics Center
Re: [PATCH 06/12] drm/i915/dvo: Populate connector->ddc
On Tue, 29 Aug 2023, Ville Syrjala wrote: > From: Ville Syrjälä > > Populate connector->ddc, and thus create the "ddc" symlink > in sysfs for DVO connectors. > > Signed-off-by: Ville Syrjälä Reviewed-by: Jani Nikula > --- > drivers/gpu/drm/i915/display/intel_dvo.c | 11 +-- > 1 file changed, 5 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c > b/drivers/gpu/drm/i915/display/intel_dvo.c > index b386894c3a6d..d9f427856fb8 100644 > --- a/drivers/gpu/drm/i915/display/intel_dvo.c > +++ b/drivers/gpu/drm/i915/display/intel_dvo.c > @@ -328,7 +328,6 @@ intel_dvo_detect(struct drm_connector *_connector, bool > force) > static int intel_dvo_get_modes(struct drm_connector *_connector) > { > struct intel_connector *connector = to_intel_connector(_connector); > - struct drm_i915_private *i915 = to_i915(connector->base.dev); > int num_modes; > > /* > @@ -337,8 +336,7 @@ static int intel_dvo_get_modes(struct drm_connector > *_connector) >* (TV-out, for example), but for now with just TMDS and LVDS, >* that's not the case. >*/ > - num_modes = intel_ddc_get_modes(&connector->base, > - intel_gmbus_get_adapter(i915, > GMBUS_PIN_DPC)); > + num_modes = intel_ddc_get_modes(&connector->base, connector->base.ddc); > if (num_modes) > return num_modes; > > @@ -533,9 +531,10 @@ void intel_dvo_init(struct drm_i915_private *i915) > connector->polled = DRM_CONNECTOR_POLL_CONNECT | > DRM_CONNECTOR_POLL_DISCONNECT; > > - drm_connector_init(&i915->drm, &connector->base, > -&intel_dvo_connector_funcs, > -intel_dvo_connector_type(&intel_dvo->dev)); > + drm_connector_init_with_ddc(&i915->drm, &connector->base, > + &intel_dvo_connector_funcs, > + intel_dvo_connector_type(&intel_dvo->dev), > + intel_gmbus_get_adapter(i915, > GMBUS_PIN_DPC)); > > drm_connector_helper_add(&connector->base, >&intel_dvo_connector_helper_funcs); -- Jani Nikula, Intel Open Source Graphics Center
Re: [PATCH 07/12] drm/i915/dp: Populate connector->ddc
On Tue, 29 Aug 2023, Ville Syrjala wrote: > From: Ville Syrjälä > > Populate connector->ddc, and thus create the "ddc" symlink > in sysfs for analog DP SST connectors. > > Let's also reorder intel_dp_aux_init() vs. drm_connector_init_with_ddc() > a bit to make sure the i2c aux ch is at least somewhat populated > before we pass it on, though drm_connector_init_with_ddc() does > not actually do anything with it. > > Signed-off-by: Ville Syrjälä Reviewed-by: Jani Nikula > --- > drivers/gpu/drm/i915/display/intel_dp.c | 9 + > 1 file changed, 5 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c > b/drivers/gpu/drm/i915/display/intel_dp.c > index 05694e0b6143..9b35b1d6adbb 100644 > --- a/drivers/gpu/drm/i915/display/intel_dp.c > +++ b/drivers/gpu/drm/i915/display/intel_dp.c > @@ -5914,7 +5914,7 @@ static bool intel_edp_init_connector(struct intel_dp > *intel_dp, > } > > mutex_lock(&dev_priv->drm.mode_config.mutex); > - drm_edid = drm_edid_read_ddc(connector, &intel_dp->aux.ddc); > + drm_edid = drm_edid_read_ddc(connector, connector->ddc); > if (!drm_edid) { > /* Fallback to EDID from ACPI OpRegion, if any */ > drm_edid = intel_opregion_get_edid(intel_connector); > @@ -6053,12 +6053,15 @@ intel_dp_init_connector(struct intel_digital_port > *dig_port, > if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) > intel_dp->pps.active_pipe = vlv_active_pipe(intel_dp); > > + intel_dp_aux_init(intel_dp); > + > drm_dbg_kms(&dev_priv->drm, > "Adding %s connector on [ENCODER:%d:%s]\n", > type == DRM_MODE_CONNECTOR_eDP ? "eDP" : "DP", > intel_encoder->base.base.id, intel_encoder->base.name); > > - drm_connector_init(dev, connector, &intel_dp_connector_funcs, type); > + drm_connector_init_with_ddc(dev, connector, &intel_dp_connector_funcs, > + type, &intel_dp->aux.ddc); > drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); > > if (!HAS_GMCH(dev_priv) && DISPLAY_VER(dev_priv) < 12) > @@ -6066,8 +6069,6 @@ intel_dp_init_connector(struct intel_digital_port > *dig_port, > > intel_connector->polled = DRM_CONNECTOR_POLL_HPD; > > - intel_dp_aux_init(intel_dp); > - > intel_connector_attach_encoder(intel_connector, intel_encoder); > > if (HAS_DDI(dev_priv)) -- Jani Nikula, Intel Open Source Graphics Center
Re: [PATCH 08/12] drm/i915/mst: Populate connector->ddc
On Tue, 29 Aug 2023, Ville Syrjala wrote: > From: Ville Syrjälä > > Populate connector->ddc, and thus create the "ddc" symlink > in sysfs for DP MST connectors. > > TODO: test that this actually works :) Seems legit, Reviewed-by: Jani Nikula > > References: https://gitlab.freedesktop.org/drm/intel/-/issues/3605 > Signed-off-by: Ville Syrjälä > --- > drivers/gpu/drm/i915/display/intel_dp_mst.c | 6 -- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c > b/drivers/gpu/drm/i915/display/intel_dp_mst.c > index 2d1c42a5e684..0bf02a29e371 100644 > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c > @@ -1104,8 +1104,10 @@ static struct drm_connector > *intel_dp_add_mst_connector(struct drm_dp_mst_topolo > drm_dp_mst_get_port_malloc(port); > > connector = &intel_connector->base; > - ret = drm_connector_init(dev, connector, &intel_dp_mst_connector_funcs, > - DRM_MODE_CONNECTOR_DisplayPort); > + ret = drm_connector_init_with_ddc(dev, connector, > + &intel_dp_mst_connector_funcs, > + DRM_MODE_CONNECTOR_DisplayPort, > + &port->aux.ddc); > if (ret) { > drm_dp_mst_put_port_malloc(port); > intel_connector_free(intel_connector); -- Jani Nikula, Intel Open Source Graphics Center
Re: [Intel-gfx] [PATCH 09/12] drm/i915/hdmi: Use connector->ddc everwhere
On Tue, 29 Aug 2023, Ville Syrjala wrote: > From: Ville Syrjälä > > We already populate connector->ddc for HDMI ports, but > so far we've not taken full advantage of it. Do that by > eliminating a bunch of intel_gmbus_get_adapter() lookups. > > Signed-off-by: Ville Syrjälä Reviewed-by: Jani Nikula > --- > drivers/gpu/drm/i915/display/intel_ddi.c | 3 +- > drivers/gpu/drm/i915/display/intel_hdmi.c | 37 --- > 2 files changed, 14 insertions(+), 26 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c > b/drivers/gpu/drm/i915/display/intel_ddi.c > index e6cc4dab3201..d86ce93fb57f 100644 > --- a/drivers/gpu/drm/i915/display/intel_ddi.c > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c > @@ -4323,8 +4323,7 @@ static int intel_hdmi_reset_link(struct intel_encoder > *encoder, > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > struct intel_hdmi *hdmi = enc_to_intel_hdmi(encoder); > struct intel_connector *connector = hdmi->attached_connector; > - struct i2c_adapter *ddc = > - intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus); > + struct i2c_adapter *ddc = connector->base.ddc; > struct drm_connector_state *conn_state; > struct intel_crtc_state *crtc_state; > struct intel_crtc *crtc; > diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c > b/drivers/gpu/drm/i915/display/intel_hdmi.c > index 82f9a40b34e3..efa9bb93cfb1 100644 > --- a/drivers/gpu/drm/i915/display/intel_hdmi.c > +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c > @@ -1240,7 +1240,7 @@ static void hsw_set_infoframes(struct intel_encoder > *encoder, > void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable) > { > struct drm_i915_private *dev_priv = intel_hdmi_to_i915(hdmi); > - struct i2c_adapter *ddc = intel_gmbus_get_adapter(dev_priv, > hdmi->ddc_bus); > + struct i2c_adapter *ddc = hdmi->attached_connector->base.ddc; > > if (hdmi->dp_dual_mode.type < DRM_DP_DUAL_MODE_TYPE2_DVI) > return; > @@ -1255,9 +1255,8 @@ void intel_dp_dual_mode_set_tmds_output(struct > intel_hdmi *hdmi, bool enable) > static int intel_hdmi_hdcp_read(struct intel_digital_port *dig_port, > unsigned int offset, void *buffer, size_t size) > { > - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); > struct intel_hdmi *hdmi = &dig_port->hdmi; > - struct i2c_adapter *ddc = intel_gmbus_get_adapter(i915, hdmi->ddc_bus); > + struct i2c_adapter *ddc = hdmi->attached_connector->base.ddc; > int ret; > u8 start = offset & 0xff; > struct i2c_msg msgs[] = { > @@ -1283,9 +1282,8 @@ static int intel_hdmi_hdcp_read(struct > intel_digital_port *dig_port, > static int intel_hdmi_hdcp_write(struct intel_digital_port *dig_port, >unsigned int offset, void *buffer, size_t size) > { > - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); > struct intel_hdmi *hdmi = &dig_port->hdmi; > - struct i2c_adapter *ddc = intel_gmbus_get_adapter(i915, hdmi->ddc_bus); > + struct i2c_adapter *ddc = hdmi->attached_connector->base.ddc; > int ret; > u8 *write_buf; > struct i2c_msg msg; > @@ -1318,7 +1316,7 @@ int intel_hdmi_hdcp_write_an_aksv(struct > intel_digital_port *dig_port, > { > struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); > struct intel_hdmi *hdmi = &dig_port->hdmi; > - struct i2c_adapter *ddc = intel_gmbus_get_adapter(i915, hdmi->ddc_bus); > + struct i2c_adapter *ddc = hdmi->attached_connector->base.ddc; > int ret; > > ret = intel_hdmi_hdcp_write(dig_port, DRM_HDCP_DDC_AN, an, > @@ -2398,8 +2396,10 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector > *connector) > struct drm_i915_private *dev_priv = to_i915(connector->dev); > struct intel_hdmi *hdmi = > intel_attached_hdmi(to_intel_connector(connector)); > struct intel_encoder *encoder = &hdmi_to_dig_port(hdmi)->base; > - struct i2c_adapter *ddc = intel_gmbus_get_adapter(dev_priv, > hdmi->ddc_bus); > - enum drm_dp_dual_mode_type type = > drm_dp_dual_mode_detect(&dev_priv->drm, ddc); > + struct i2c_adapter *ddc = connector->ddc; > + enum drm_dp_dual_mode_type type; > + > + type = drm_dp_dual_mode_detect(&dev_priv->drm, ddc); > > /* >* Type 1 DVI adaptors are not required to implement any > @@ -2447,7 +2447,7 @@ intel_hdmi_set_edid(struct drm_connector *connector) > { > struct drm_i915_private *dev_priv = to_i915(connector->dev); > struct intel_hdmi *intel_hdmi = > intel_attached_hdmi(to_intel_connector(connector)); > - struct i2c_adapter *ddc = intel_gmbus_get_adapter(dev_priv, > intel_hdmi->ddc_bus); > + struct i2c_adapter *ddc = connector->ddc; > intel_wakeref_t wakeref; > const struct drm_edid *drm_edid; > const struct edid *edid; > @@ -2544,19 +2544,10 @@ st
Re: [Intel-gfx] [PATCH 12/12] drm/i915/sdvo: Constify mapping structs
On Tue, 29 Aug 2023, Ville Syrjala wrote: > From: Ville Syrjälä > > We aren't intending to mutate the SDVO device mapping structs, > so make them const. > > Signed-off-by: Ville Syrjälä Reviewed-by: Jani Nikula > --- > drivers/gpu/drm/i915/display/intel_sdvo.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c > b/drivers/gpu/drm/i915/display/intel_sdvo.c > index b988e05274c1..0bd815bf2e69 100644 > --- a/drivers/gpu/drm/i915/display/intel_sdvo.c > +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c > @@ -2579,7 +2579,7 @@ intel_sdvo_select_ddc_bus(struct intel_sdvo *sdvo, > struct intel_sdvo_connector *connector) > { > struct drm_i915_private *dev_priv = to_i915(sdvo->base.base.dev); > - struct sdvo_device_mapping *mapping; > + const struct sdvo_device_mapping *mapping; > int ddc_bus; > > if (sdvo->base.port == PORT_B) > @@ -2602,7 +2602,7 @@ static void > intel_sdvo_select_i2c_bus(struct intel_sdvo *sdvo) > { > struct drm_i915_private *dev_priv = to_i915(sdvo->base.base.dev); > - struct sdvo_device_mapping *mapping; > + const struct sdvo_device_mapping *mapping; > u8 pin; > > if (sdvo->base.port == PORT_B) > @@ -2647,7 +2647,7 @@ static u8 > intel_sdvo_get_slave_addr(struct intel_sdvo *sdvo) > { > struct drm_i915_private *dev_priv = to_i915(sdvo->base.base.dev); > - struct sdvo_device_mapping *my_mapping, *other_mapping; > + const struct sdvo_device_mapping *my_mapping, *other_mapping; > > if (sdvo->base.port == PORT_B) { > my_mapping = &dev_priv->display.vbt.sdvo_mappings[0]; -- Jani Nikula, Intel Open Source Graphics Center
Re: [RFC 01/33] drm/doc/rfc: Add RFC document for proposed Plane Color Pipeline
On Wed, 30 Aug 2023 08:59:36 + "Shankar, Uma" wrote: > > -Original Message- > > From: Harry Wentland > > Sent: Wednesday, August 30, 2023 1:10 AM > > To: Shankar, Uma ; intel-...@lists.freedesktop.org; > > dri- > > de...@lists.freedesktop.org > > Cc: Borah, Chaitanya Kumar ; wayland- > > de...@lists.freedesktop.org > > Subject: Re: [RFC 01/33] drm/doc/rfc: Add RFC document for proposed Plane > > Color > > Pipeline > > > > > > > > On 2023-08-29 12:03, Uma Shankar wrote: > > > Add the documentation for the new proposed Plane Color Pipeline. > > > > > > Co-developed-by: Chaitanya Kumar Borah > > > > > > Signed-off-by: Chaitanya Kumar Borah > > > Signed-off-by: Uma Shankar > > > --- > > > .../gpu/rfc/plane_color_pipeline.rst | 394 ++ > > > 1 file changed, 394 insertions(+) > > > create mode 100644 Documentation/gpu/rfc/plane_color_pipeline.rst > > > > > > diff --git a/Documentation/gpu/rfc/plane_color_pipeline.rst > > > b/Documentation/gpu/rfc/plane_color_pipeline.rst > > > new file mode 100644 > > > index ..60ce515b6ea7 > > > --- /dev/null > > > +++ b/Documentation/gpu/rfc/plane_color_pipeline.rst ... Hi Uma! > > > +This color pipeline is then packaged within a blob for the user space > > > +to retrieve it. Details can be found in the next section > > > + > > > > Not sure I like blobs that contain other blob ids. > > It provides flexibility and helps with just one interface to userspace. Its > easy to handle and > manage once we get the hang of it 😊. > > We can clearly define the steps of parsing and data structures to be used > while interpreting > and parsing the blobs. Don't forget extendability. Possibly every single struct will need some kind of versioning, and then it's not simple to parse anymore. Add to that new/old kernel vs. old/new userspace, and it seems a bit nightmarish to design. Also since it's records inside a single blob, it's like a new file format: every record needs a standard header that allows skipping it appropriately if userspace does not understand it, or you need a standard index telling where everything is. Making all records the same size would waste space, and extendability requires variable size. I also would not assume that we can declare a standard set of blocks and that nothing else will be needed. The existing hardware is too diverse for that from what I have understood. I assume that some hardware have blocks unique to them, and they want to at least expose that functionality through a UAPI that allows at least generic enumeration of functionality, even if it needs specialized userspace code to actually make use of. If we go with +struct drm_color_op { + enum color_op_block name; + enum color_op_type type; + u32 blob_id; + u32 private_flags; +}; as in your proposal, I believe it can work (sorry, looking further down, I have assumed too much of 'type'), but the enumerations will become long, and the details blob_id is still specific to 'type'. This is unavoidable, but we can still choose the form between blobs and properties, integers and strings. I have a feeling that introspection will be valuable here, to help people understand what their hardware could do if they had the code to use it. 'name' and 'type' being integers require a translation table to strings before they are readable, and it would be best if the kernel itself provided that translation. I don't understand how 'private_flags' could be useful. There must not be any "hidden" features. Everything a block can be programmed to do via this UAPI must be clearly documented, there cannot be anything private. If two hardware versions of a block differ in a meaningful or significant way, they need to be exposed as different types of blocks. OTOH, if one goes with a (new) DRM object with string named properties model, all that struct versioning and file format hassle has mostly a clear and well-understood solution. We only need to define the rules of how userspace needs to deal with properties or values it does not understand, so that the kernel can keep adding more. Therefore, I'm not yet convinced with the "all blobs" design. > > > +Exposing a color pipeline to user space > > > +=== > > > + > > > +To advertise the available color pipelines, an immutable ENUM > > > +property "GET_COLOR_PIPELINE" is introduced. > > > +This enum property has blob id's as values. With each blob id > > > +representing a distinct color pipeline based on underlying HW > > > +capabilities and their respective combinations. > > > + > > > +The following output of drm_info [1], shows how color pipelines are > > > +visible to userspace. > > > + > > > +├───Plane 0 > > > +│ ├───Object ID: 31 > > > +│ ├───CRTCs: {0} > > > +│ ├───Legacy info > > > +... > > > +│ ├───"GET_COLOR_PIPELINE" (immutable): enum {no color > > > pipeline, > > > +
Re: [PATCH drm-misc-next 2/3] drm/gpuva_mgr: generalize dma_resv/extobj handling and GEM validation
Hi Thomas, thanks for having a look! On Wed, Aug 30, 2023 at 09:27:45AM +0200, Thomas Hellström (Intel) wrote: > Hi, Danilo. > > Some quick comments since I'm doing some Xe work in this area. Will probably > get back with more. > > On 8/20/23 23:53, Danilo Krummrich wrote: > > So far the DRM GPUVA manager offers common infrastructure to track GPU VA > > allocations and mappings, generically connect GPU VA mappings to their > > backing buffers and perform more complex mapping operations on the GPU VA > > space. > > > > However, there are more design patterns commonly used by drivers, which > > can potentially be generalized in order to make the DRM GPUVA manager > > represent a basic GPU-VM implementation. In this context, this patch aims > > at generalizing the following elements. > > > > 1) Provide a common dma-resv for GEM objects not being used outside of > > this GPU-VM. > > > > 2) Provide tracking of external GEM objects (GEM objects which are > > shared with other GPU-VMs). > > > > 3) Provide functions to efficiently lock all GEM objects dma-resv the > > GPU-VM contains mappings of. > > > > 4) Provide tracking of evicted GEM objects the GPU-VM contains mappings > > of, such that validation of evicted GEM objects is accelerated. > > > > 5) Provide some convinience functions for common patterns. > > > > Rather than being designed as a "framework", the target is to make all > > features appear as a collection of optional helper functions, such that > > drivers are free to make use of the DRM GPUVA managers basic > > functionality and opt-in for other features without setting any feature > > flags, just by making use of the corresponding functions. > > > > Signed-off-by: Danilo Krummrich > > --- > > drivers/gpu/drm/drm_gpuva_mgr.c | 688 +++- > > include/drm/drm_gem.h | 48 ++- > > include/drm/drm_gpuva_mgr.h | 302 +- > > 3 files changed, 1010 insertions(+), 28 deletions(-) > > > > diff --git a/drivers/gpu/drm/drm_gpuva_mgr.c > > b/drivers/gpu/drm/drm_gpuva_mgr.c > > index f86bfad74ff8..69872b205961 100644 > > --- a/drivers/gpu/drm/drm_gpuva_mgr.c > > +++ b/drivers/gpu/drm/drm_gpuva_mgr.c > > @@ -655,6 +655,7 @@ drm_gpuva_range_valid(struct drm_gpuva_manager *mgr, > > /** > >* drm_gpuva_manager_init() - initialize a &drm_gpuva_manager > >* @mgr: pointer to the &drm_gpuva_manager to initialize > > + * @drm: the drivers &drm_device > >* @name: the name of the GPU VA space > >* @start_offset: the start offset of the GPU VA space > >* @range: the size of the GPU VA space > > @@ -669,6 +670,7 @@ drm_gpuva_range_valid(struct drm_gpuva_manager *mgr, > >*/ > > void > > drm_gpuva_manager_init(struct drm_gpuva_manager *mgr, > > + struct drm_device *drm, > >const char *name, > >u64 start_offset, u64 range, > >u64 reserve_offset, u64 reserve_range, > > @@ -677,6 +679,11 @@ drm_gpuva_manager_init(struct drm_gpuva_manager *mgr, > > mgr->rb.tree = RB_ROOT_CACHED; > > INIT_LIST_HEAD(&mgr->rb.list); > > + mt_init(&mgr->mt_ext); > > + > > + INIT_LIST_HEAD(&mgr->evict.list); > > + spin_lock_init(&mgr->evict.lock); > > + > > drm_gpuva_check_overflow(start_offset, range); > > mgr->mm_start = start_offset; > > mgr->mm_range = range; > > @@ -694,6 +701,9 @@ drm_gpuva_manager_init(struct drm_gpuva_manager *mgr, > > reserve_range))) > > __drm_gpuva_insert(mgr, &mgr->kernel_alloc_node); > > } > > + > > + drm_gem_private_object_init(drm, &mgr->d_obj, 0); > > + mgr->resv = mgr->d_obj.resv; > > } > > EXPORT_SYMBOL_GPL(drm_gpuva_manager_init); > > @@ -713,10 +723,575 @@ drm_gpuva_manager_destroy(struct drm_gpuva_manager > > *mgr) > > __drm_gpuva_remove(&mgr->kernel_alloc_node); > > WARN(!RB_EMPTY_ROOT(&mgr->rb.tree.rb_root), > > -"GPUVA tree is not empty, potentially leaking memory."); > > +"GPUVA tree is not empty, potentially leaking memory.\n"); > > + > > + mtree_destroy(&mgr->mt_ext); > > + WARN(!list_empty(&mgr->evict.list), "Evict list should be empty.\n"); > > + > > + drm_gem_private_object_fini(&mgr->d_obj); > > } > > EXPORT_SYMBOL_GPL(drm_gpuva_manager_destroy); > > +/** > > + * drm_gpuva_manager_prepare_objects() - prepare all assoiciated BOs > > + * @mgr: the &drm_gpuva_manager > > + * @num_fences: the amount of &dma_fences to reserve > > + * > > + * Calls drm_exec_prepare_obj() for all &drm_gem_objects the given > > + * &drm_gpuva_manager contains mappings of. > > + * > > + * Drivers can obtain the corresponding &drm_exec instance through > > + * DRM_GPUVA_EXEC(). It is the drivers responsibility to call > > drm_exec_init() > > + * and drm_exec_fini() accordingly. > > + * > > + * Returns: 0 on success, negative error code on failure. > > + */ > > +int > > +drm_gpuva_manager_prep
Re: [RFC 02/33] drm: Add color operation structure
On Tue, 29 Aug 2023 21:33:51 +0530 Uma Shankar wrote: > From: Chaitanya Kumar Borah > > Each Color Hardware block will be represented uniquely > in the color pipeline. Define the structure to represent > the same. > > These color operations will form the building blocks of > a color pipeline which best represents the underlying > Hardware. Color operations can be re-arranged, substracted > or added to create distinct color pipelines to accurately > describe the Hardware blocks present in the display engine. > > Co-developed-by: Uma Shankar > Signed-off-by: Uma Shankar > Signed-off-by: Chaitanya Kumar Borah > --- > include/uapi/drm/drm_mode.h | 72 + > 1 file changed, 72 insertions(+) > > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h > index ea1b639bcb28..882479f41745 100644 > --- a/include/uapi/drm/drm_mode.h > +++ b/include/uapi/drm/drm_mode.h > @@ -943,6 +943,78 @@ struct hdr_output_metadata { > }; > }; > > +/** > + * enum color_op_block > + * > + * Enums to identify hardware color blocks. > + * > + * @DRM_CB_PRE_CSC: LUT before the CTM unit > + * @DRM_CB_CSC: CTM hardware supporting 3x3 matrix > + * @DRM_CB_POST_CSC: LUT after the CTM unit > + * @DRM_CB_3D_LUT: LUT hardware with coefficients for all > + * color components > + * @DRM_CB_PRIVATE: Vendor specific hardware unit. Vendor > + * can expose a custom hardware by defining a > + * color operation block with this name as > + * identifier This naming scheme does not seem to work. It assumes a far too rigid pipeline, just like the old KMS property design. What if you have two other operations between PRE_CSC and CSC? What sense do PRE_CSC and POST_CSC make if you don't happen to have a CSC operation? What if a driver put POST_CSC before PRE_CSC in its pipeline? What if your CSC is actually a series of three independent operations, and in addition you have PRE_CSC and POST_CSC? 3D_LUT is an operation category, not a name. The same could be said about private. Given that all these are also UAPI, do we also need protect old userspace from seeing values it does not understand? > + */ > +enum color_op_block { > + DRM_CB_INVAL = -1, > + > + DRM_CB_PRE_CSC = 0, > + DRM_CB_CSC, > + DRM_CB_POST_CSC, > + DRM_CB_3D_LUT, > + > + /* Any new generic hardware block can be updated here */ > + > + /* > + * PRIVATE is kept at 255 to make it future proof and leave > + * scope for any new addition > + */ > + DRM_CB_PRIVATE = 255, > + DRM_CB_MAX = DRM_CB_PRIVATE, > +}; > + > +/** > + * enum color_op_type > + * > + * These enums are to identify the mathematical operation that > + * a hardware block is capable of. > + * @CURVE_1D: It represents a one dimensional lookup table > + * @CURVE_3D: Represents lut value for each color component for 3d lut > capable hardware > + * @MATRIX: It represents co-efficients for a CSC/CTM matrix hardware > + * @FIXED_FUNCTION: To enable and program any custom fixed function hardware > unit > + */ > +enum color_op_type { > + CURVE_1D, > + CURVE_3D, > + MATRIX, > + FIXED_FUNCTION, My assumption was that a color_op_type would clearly and uniquely define the mathematical model of the operation and the UABI structure of the parameter blob. That means we need different values for uniform vs. exponentially vs. programmable distributed 1D LUT, etc. If there is a 1D curve with pre-programmed (fixed and named) curves, we need to enumerate all the curve types somehow. Probably each fixed curve type should not be a different operation type, because that would explode the number of alternative pipelines. A 3D curve in my mind is a function {x,y,z} = f(t), while I suspect you meant a 3D LUT which is a {x,y,z} = f(t,u,v) - a 3-vector field in three dimensional space. A matrix element could be with or without an offset vector I guess. FIXED_FUNCTION would need to be replaced with e.g. your example VENDORXXX_BT602_TO_BT2020 to work. Have I missed something, how did you intend this to work? Thanks, pq > +}; > + > +/** > + * @struct drm_color_op > + * > + * This structure is used to represent the capability of > + * individual color hardware blocks. > + * > + * @name: a standardized enum to identify the color hardware block > + * @type: The type of mathematical operation it can perform > + * @blob_id: Id pointing to a blob containing information about > + * the hardware block which advertizes its capabilities > + * to the userspace. It can be an optional field depending > + * on the members "name" and "type". > + * @private_flags: This can be used to provide vendor specific hints > + * to user space > + */ > +struct drm_color_op { > + enum color_op_block name; > + enum color_op_type type; > + __u32 blob_id; > + __u32 private_flags; > +}; > + > /** > * DRM_MODE_PAGE_FLIP
Re: [PATCH drm-misc-next 2/3] drm/gpuva_mgr: generalize dma_resv/extobj handling and GEM validation
On Wed, Aug 30, 2023 at 09:48:02AM +0200, Christian König wrote: > > > Am 20.08.23 um 23:53 schrieb Danilo Krummrich: > > So far the DRM GPUVA manager offers common infrastructure to track GPU VA > > allocations and mappings, generically connect GPU VA mappings to their > > backing buffers and perform more complex mapping operations on the GPU VA > > space. > > > > However, there are more design patterns commonly used by drivers, which > > can potentially be generalized in order to make the DRM GPUVA manager > > represent a basic GPU-VM implementation. In this context, this patch aims > > at generalizing the following elements. > > > > 1) Provide a common dma-resv for GEM objects not being used outside of > > this GPU-VM. > > > > 2) Provide tracking of external GEM objects (GEM objects which are > > shared with other GPU-VMs). > > > > 3) Provide functions to efficiently lock all GEM objects dma-resv the > > GPU-VM contains mappings of. > > > > 4) Provide tracking of evicted GEM objects the GPU-VM contains mappings > > of, such that validation of evicted GEM objects is accelerated. > > > > 5) Provide some convinience functions for common patterns. > > Interesting work. > > You basically implement a bunch of the ideas I came up to improve the amdgpu > performance in the common manager now. The was one of the remaining blockers > I had for using this in amdgpu. > > Question is for example how do you track evictions? E.g. we don't have a > common concept of eviction in GEM as far as I know. Or is the driver > responsible for giving those notifications to the GPUVA manager? Right, it is the driver being responsible to adding a drm_gpuva_gem (or VM_BO) to the managers evict list. The idea was that drivers have control about the state of a drm_gpuva_gem, such that a driver can move it to driver specific lists as well, like all the ones you have in amdgpu. > > And would it be possible to lock only a specific area of the VM, e.g. every > BO mapped in the interval X..Y? Currently, the drm_gpuva_manager_lock() functions always lock the GPU-VMs dma-resv lock, plus all the dma-resv locks of the external objects the manager keeps track of. But surely, we could also add something like drm_gpuva_manager_lock_range() where we just iterate all drm_gpuvas between X and Y and lock the dma-resv locks of each drm_gpuva's backing BO. > > Regards, > Christian. > > > > > Rather than being designed as a "framework", the target is to make all > > features appear as a collection of optional helper functions, such that > > drivers are free to make use of the DRM GPUVA managers basic > > functionality and opt-in for other features without setting any feature > > flags, just by making use of the corresponding functions. > > > > Signed-off-by: Danilo Krummrich > > --- > > drivers/gpu/drm/drm_gpuva_mgr.c | 688 +++- > > include/drm/drm_gem.h | 48 ++- > > include/drm/drm_gpuva_mgr.h | 302 +- > > 3 files changed, 1010 insertions(+), 28 deletions(-) > > > > diff --git a/drivers/gpu/drm/drm_gpuva_mgr.c > > b/drivers/gpu/drm/drm_gpuva_mgr.c > > index f86bfad74ff8..69872b205961 100644 > > --- a/drivers/gpu/drm/drm_gpuva_mgr.c > > +++ b/drivers/gpu/drm/drm_gpuva_mgr.c > > @@ -655,6 +655,7 @@ drm_gpuva_range_valid(struct drm_gpuva_manager *mgr, > > /** > >* drm_gpuva_manager_init() - initialize a &drm_gpuva_manager > >* @mgr: pointer to the &drm_gpuva_manager to initialize > > + * @drm: the drivers &drm_device > >* @name: the name of the GPU VA space > >* @start_offset: the start offset of the GPU VA space > >* @range: the size of the GPU VA space > > @@ -669,6 +670,7 @@ drm_gpuva_range_valid(struct drm_gpuva_manager *mgr, > >*/ > > void > > drm_gpuva_manager_init(struct drm_gpuva_manager *mgr, > > + struct drm_device *drm, > >const char *name, > >u64 start_offset, u64 range, > >u64 reserve_offset, u64 reserve_range, > > @@ -677,6 +679,11 @@ drm_gpuva_manager_init(struct drm_gpuva_manager *mgr, > > mgr->rb.tree = RB_ROOT_CACHED; > > INIT_LIST_HEAD(&mgr->rb.list); > > + mt_init(&mgr->mt_ext); > > + > > + INIT_LIST_HEAD(&mgr->evict.list); > > + spin_lock_init(&mgr->evict.lock); > > + > > drm_gpuva_check_overflow(start_offset, range); > > mgr->mm_start = start_offset; > > mgr->mm_range = range; > > @@ -694,6 +701,9 @@ drm_gpuva_manager_init(struct drm_gpuva_manager *mgr, > > reserve_range))) > > __drm_gpuva_insert(mgr, &mgr->kernel_alloc_node); > > } > > + > > + drm_gem_private_object_init(drm, &mgr->d_obj, 0); > > + mgr->resv = mgr->d_obj.resv; > > } > > EXPORT_SYMBOL_GPL(drm_gpuva_manager_init); > > @@ -713,10 +723,575 @@ drm_gpuva_manager_destroy(struct drm_gpuva_manager > > *mgr) > > __drm_gpuva_remove(&mgr->kernel_alloc_
Re: [PATCH v2 04/15] drm/panthor: Add the device logical block
On 29/08/2023 15:00, Boris Brezillon wrote: > On Fri, 11 Aug 2023 16:47:56 +0100 > Steven Price wrote: > >> On 09/08/2023 17:53, Boris Brezillon wrote: >>> The panthor driver is designed in a modular way, where each logical >>> block is dealing with a specific HW-block or software feature. In order >>> for those blocks to communicate with each other, we need a central >>> panthor_device collecting all the blocks, and exposing some common >>> features, like interrupt handling, power management, reset, ... >>> >>> This what this panthor_device logical block is about. >>> >>> v2: >>> - Rename the driver (pancsf -> panthor) >>> - Change the license (GPL2 -> MIT + GPL2) >>> - Split the driver addition commit >>> - Add devfreq/PM support >>> - Use drm_dev_{unplug,enter,exit}() to provide safe device removal >>> >>> Signed-off-by: Boris Brezillon >>> --- >>> drivers/gpu/drm/panthor/panthor_device.c | 479 +++ >>> drivers/gpu/drm/panthor/panthor_device.h | 354 + >>> 2 files changed, 833 insertions(+) >>> create mode 100644 drivers/gpu/drm/panthor/panthor_device.c >>> create mode 100644 drivers/gpu/drm/panthor/panthor_device.h >>> >>> diff --git a/drivers/gpu/drm/panthor/panthor_device.c >>> b/drivers/gpu/drm/panthor/panthor_device.c >>> new file mode 100644 >>> index ..15f102116fa0 >>> --- /dev/null >>> +++ b/drivers/gpu/drm/panthor/panthor_device.c >>> @@ -0,0 +1,479 @@ >>> +// SPDX-License-Identifier: GPL-2.0 or MIT >>> +/* Copyright 2018 Marty E. Plummer */ >>> +/* Copyright 2019 Linaro, Ltd, Rob Herring */ >>> +/* Copyright 2023 Collabora ltd. */ >>> + >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> + >>> +#include >>> +#include >>> + >>> +#include "panthor_sched.h" >>> +#include "panthor_device.h" >>> +#include "panthor_devfreq.h" >>> +#include "panthor_gpu.h" >>> +#include "panthor_fw.h" >>> +#include "panthor_mmu.h" >>> +#include "panthor_regs.h" >>> + >>> +static int panthor_clk_init(struct panthor_device *ptdev) >>> +{ >>> + ptdev->clks.core = devm_clk_get(ptdev->base.dev, NULL); >>> + if (IS_ERR(ptdev->clks.core)) { >>> + drm_err(&ptdev->base, "get 'core' clock failed %ld\n", >>> + PTR_ERR(ptdev->clks.core)); >> >> I suspect it would be a good idea to use dev_err_probe() here (and >> below) as I believe devm_clk_get can return -EPROBE_DEFER. > > Nice, didn't know there was a logging function that was silencing > probe-defer errors. > >> >>> + return PTR_ERR(ptdev->clks.core); >>> + } >>> + >>> + ptdev->clks.stacks = devm_clk_get_optional(ptdev->base.dev, "stacks"); >>> + if (IS_ERR(ptdev->clks.stacks)) { >>> + drm_err(&ptdev->base, "get 'stacks' clock failed %ld\n", >>> + PTR_ERR(ptdev->clks.stacks)); >>> + return PTR_ERR(ptdev->clks.stacks); >>> + } >>> + >>> + ptdev->clks.coregroup = devm_clk_get_optional(ptdev->base.dev, >>> "coregroup"); >>> + if (IS_ERR(ptdev->clks.coregroup)) { >>> + drm_err(&ptdev->base, "get 'coregroup' clock failed %ld\n", >>> + PTR_ERR(ptdev->clks.coregroup)); >>> + return PTR_ERR(ptdev->clks.coregroup); >>> + } >>> + >>> + drm_info(&ptdev->base, "clock rate = %lu\n", >>> clk_get_rate(ptdev->clks.core)); >>> + return 0; >>> +} >>> + >>> +void panthor_device_unplug(struct panthor_device *ptdev) >>> +{ >>> + /* FIXME: This is racy. */ >> >> Can we fix this? From a quick look it seems like a sequence like below >> should avoid the race. >> >> if (!drm_dev_enter()) >> /* Already unplugged */ >> return; >> ptdev->base.unplugged = true; >> drm_dev_exit(); >> >> Although possibly that should be in the DRM core rather than open-coded >> here. > > Are you sure that's protecting us against two concurrent calls to > drm_dev_unplug() (drm_dev_enter() is taking a read-lock)? Well now I'm not sure ;) This was based on the implementations of drm_dev_is_unplugged() and drm_dev_unplug(). drm_dev_is_unplugged() simply tries to enter then exit. drm_dev_unplug() sets dev->unplugged (without first taking any locks). So my naïve combination resulted in the above. The part I was missing is the synchronize_srcu() call in drm_dev_unplug() is what matches up with the read lock in drm_dev_enter(). > And that's not > the only thing I need actually. If there are 2 threads entering > panthor_device_unplug(), I need to make sure the one who losts (arrived > after unplugged was set to false) is waiting for all operations after > the drm_dev_unplug() call to be done, otherwise we might return from > platform_driver->remove() before the unplug cleanups are done, and > there might still be threads/workqueues accessing device resources > while/after they get released by the device-model. I can't figure out how to do this other than adding a new atomic status bit into panthor. So something like: if (!drm_dev_ente
Re: [PATCH v11] drm: Add initial ci/ subdirectory
Hi all, Thanks for you comments. On 30/08/2023 08:37, Maxime Ripard wrote: On Wed, Aug 30, 2023 at 01:58:31PM +0300, Jani Nikula wrote: On Wed, 30 Aug 2023, Maxime Ripard wrote: On Tue, Aug 22, 2023 at 04:26:06PM +0200, Daniel Vetter wrote: On Fri, Aug 11, 2023 at 02:19:53PM -0300, Helen Koike wrote: From: Tomeu Vizoso Developers can easily execute several tests on different devices by just pushing their branch to their fork in a repository hosted on gitlab.freedesktop.org which has an infrastructure to run jobs in several runners and farms with different devices. There are also other automated tools that uprev dependencies, monitor the infra, and so on that are already used by the Mesa project, and we can reuse them too. Also, store expectations about what the DRM drivers are supposed to pass in the IGT test suite. By storing the test expectations along with the code, we can make sure both stay in sync with each other so we can know when a code change breaks those expectations. Also, include a configuration file that points to the out-of-tree CI scripts. This will allow all contributors to drm to reuse the infrastructure already in gitlab.freedesktop.org to test the driver on several generations of the hardware. Signed-off-by: Tomeu Vizoso Signed-off-by: Helen Koike Acked-by: Daniel Stone Acked-by: Rob Clark Tested-by: Rob Clark Ok I pushed this into a topic/drm-ci branch in drm.git and asked sfr to include that branch in linux-next. But also I'd like to see a lot more acks here, we should be able to at least pile up a bunch of (driver) maintainers from drm-misc in support of this. Also maybe media, at least I've heard noises that they're maybe interested too? Plus anyone else, the more the better. I'm not really convinced by that approach at all, and most of the issues I see are shown by the follow-up series here: I'm not fully convinced either, more like "let's see". In that narrow sense, ack. I don't see harm in trying, if you're also open to backing off in case it does not pan out. https://lore.kernel.org/dri-devel/20230825122435.316272-1-vignesh.ra...@collabora.com/ * We hardcode a CI farm setup into the kernel These could be out of tree. There is a version outside the kernel tree where you just point the CI configuration to a url: https://gitlab.freedesktop.org/gfx-ci/drm-ci/-/merge_requests/1 We were discussing it here https://www.linuxtv.org/cgi-bin/mailman/private/linuxtv-ci/2023-August/27.html (I guess Sima's reply didn't got into the mailing list) but the argument of not having out of tree repo is due to historical bad experience of having to sync the kernel with the code and it can become messy. * We cannot trust that the code being run is actually the one being pushed into gitlab We can improve this if this is a requirement. For DTS configuration we can work with overlays (which is the current modification on that patchset). For other changes that are not suitable to upstream (and should be rare) we can see if we work with the `-external-fixes` approach or another approach, we can check it case by case to understand why it is not suitable for upstream. * IMO, and I know we disagree here, any IGT test we enable for a given platform should work, period. Allowing failures and flaky tests just sweeps whatever issue is there under the rug. If the test is at fault, we should fix the test, if the driver / kernel is at fault, then I certainly want to know about it. I believe we need a baseline and understand the current status of tests. If you check the xfails folder in the patch you can see that I had to add a few tests on *-skips.txt since those tests crashes the system and other on *-fails.txt that are consistently not passing. Since the "any IGT test we enable for a given platform should work" is not a reality atm, we need to have a clear view about which tests are not corresponding to it, so we can start fixing. First we need to be aware of the issues so we can start fixing them, otherwise we will stay in the "no tests no failures" ground :) At least for display, where this also depends on peripheral hardware, it's not an easy problem, really. Aside from the Chamelium tests, which tests actually rely on peripheral hardware? On EDID and hotplug, sure, but that can easily be set up from the userspace, or something like https://www.lindy-international.com/HDMI-2-0-EDID-Emulator.htm?websale8=ld0101.ld021102&pi=32115 How reliable do you need it to be? How many nines? Who is going to debug the issues that need hundreds or thousands of runs to reproduce? If a commit makes some test less reliable, how long is it going to take to even see that or pinpoint that? I mean, that's also true for failures or success then. How many times do you need a test to run properly to qualify it as a meaningful test? How do you know that it's not a flaky test? Ultimately, it's about trust. If, for a giv
Re: [PATCH drm-misc-next 2/3] drm/gpuva_mgr: generalize dma_resv/extobj handling and GEM validation
On 8/30/23 14:49, Danilo Krummrich wrote: Hi Thomas, thanks for having a look! On Wed, Aug 30, 2023 at 09:27:45AM +0200, Thomas Hellström (Intel) wrote: Hi, Danilo. Some quick comments since I'm doing some Xe work in this area. Will probably get back with more. On 8/20/23 23:53, Danilo Krummrich wrote: So far the DRM GPUVA manager offers common infrastructure to track GPU VA allocations and mappings, generically connect GPU VA mappings to their backing buffers and perform more complex mapping operations on the GPU VA space. However, there are more design patterns commonly used by drivers, which can potentially be generalized in order to make the DRM GPUVA manager represent a basic GPU-VM implementation. In this context, this patch aims at generalizing the following elements. 1) Provide a common dma-resv for GEM objects not being used outside of this GPU-VM. 2) Provide tracking of external GEM objects (GEM objects which are shared with other GPU-VMs). 3) Provide functions to efficiently lock all GEM objects dma-resv the GPU-VM contains mappings of. 4) Provide tracking of evicted GEM objects the GPU-VM contains mappings of, such that validation of evicted GEM objects is accelerated. 5) Provide some convinience functions for common patterns. Rather than being designed as a "framework", the target is to make all features appear as a collection of optional helper functions, such that drivers are free to make use of the DRM GPUVA managers basic functionality and opt-in for other features without setting any feature flags, just by making use of the corresponding functions. Signed-off-by: Danilo Krummrich --- drivers/gpu/drm/drm_gpuva_mgr.c | 688 +++- include/drm/drm_gem.h | 48 ++- include/drm/drm_gpuva_mgr.h | 302 +- 3 files changed, 1010 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/drm_gpuva_mgr.c b/drivers/gpu/drm/drm_gpuva_mgr.c index f86bfad74ff8..69872b205961 100644 --- a/drivers/gpu/drm/drm_gpuva_mgr.c +++ b/drivers/gpu/drm/drm_gpuva_mgr.c @@ -655,6 +655,7 @@ drm_gpuva_range_valid(struct drm_gpuva_manager *mgr, /** * drm_gpuva_manager_init() - initialize a &drm_gpuva_manager * @mgr: pointer to the &drm_gpuva_manager to initialize + * @drm: the drivers &drm_device * @name: the name of the GPU VA space * @start_offset: the start offset of the GPU VA space * @range: the size of the GPU VA space @@ -669,6 +670,7 @@ drm_gpuva_range_valid(struct drm_gpuva_manager *mgr, */ void drm_gpuva_manager_init(struct drm_gpuva_manager *mgr, + struct drm_device *drm, const char *name, u64 start_offset, u64 range, u64 reserve_offset, u64 reserve_range, @@ -677,6 +679,11 @@ drm_gpuva_manager_init(struct drm_gpuva_manager *mgr, mgr->rb.tree = RB_ROOT_CACHED; INIT_LIST_HEAD(&mgr->rb.list); + mt_init(&mgr->mt_ext); + + INIT_LIST_HEAD(&mgr->evict.list); + spin_lock_init(&mgr->evict.lock); + drm_gpuva_check_overflow(start_offset, range); mgr->mm_start = start_offset; mgr->mm_range = range; @@ -694,6 +701,9 @@ drm_gpuva_manager_init(struct drm_gpuva_manager *mgr, reserve_range))) __drm_gpuva_insert(mgr, &mgr->kernel_alloc_node); } + + drm_gem_private_object_init(drm, &mgr->d_obj, 0); + mgr->resv = mgr->d_obj.resv; } EXPORT_SYMBOL_GPL(drm_gpuva_manager_init); @@ -713,10 +723,575 @@ drm_gpuva_manager_destroy(struct drm_gpuva_manager *mgr) __drm_gpuva_remove(&mgr->kernel_alloc_node); WARN(!RB_EMPTY_ROOT(&mgr->rb.tree.rb_root), -"GPUVA tree is not empty, potentially leaking memory."); +"GPUVA tree is not empty, potentially leaking memory.\n"); + + mtree_destroy(&mgr->mt_ext); + WARN(!list_empty(&mgr->evict.list), "Evict list should be empty.\n"); + + drm_gem_private_object_fini(&mgr->d_obj); } EXPORT_SYMBOL_GPL(drm_gpuva_manager_destroy); +/** + * drm_gpuva_manager_prepare_objects() - prepare all assoiciated BOs + * @mgr: the &drm_gpuva_manager + * @num_fences: the amount of &dma_fences to reserve + * + * Calls drm_exec_prepare_obj() for all &drm_gem_objects the given + * &drm_gpuva_manager contains mappings of. + * + * Drivers can obtain the corresponding &drm_exec instance through + * DRM_GPUVA_EXEC(). It is the drivers responsibility to call drm_exec_init() + * and drm_exec_fini() accordingly. + * + * Returns: 0 on success, negative error code on failure. + */ +int +drm_gpuva_manager_prepare_objects(struct drm_gpuva_manager *mgr, + unsigned int num_fences) +{ + struct drm_exec *exec = DRM_GPUVA_EXEC(mgr); + MA_STATE(mas, &mgr->mt_ext, 0, 0); + union { + void *ptr; + uintptr_t cnt; +
[PATCH 0/5] Introduce new wrappers to copy user-arrays
Hi! David Airlie suggested that we could implement new wrappers around (v)memdup_user() for duplicating user arrays. This small patch series first implements the two new wrapper functions memdup_array_user() and vmemdup_array_user(). They calculate the array-sizes safely, i.e., they return an error in case of an overflow. It then implements the new wrappers in two components in kernel/ and two in the drm-subsystem. In total, there are 18 files in the kernel that use (v)memdup_user() to duplicate arrays. My plan is to provide patches for the other 14 successively once this series has been merged. P. Philipp Stanner (5): string.h: add array-wrappers for (v)memdup_user() kernel: kexec: copy user-array safely kernel: watch_queue: copy user-array safely drm_lease.c: copy user-array safely drm: vmgfx_surface.c: copy user-array safely drivers/gpu/drm/drm_lease.c | 4 +-- drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 4 +-- include/linux/string.h | 42 + kernel/kexec.c | 2 +- kernel/watch_queue.c| 2 +- 5 files changed, 48 insertions(+), 6 deletions(-) -- 2.41.0
[PATCH 1/5] string.h: add array-wrappers for (v)memdup_user()
Currently, user array duplications are sometimes done without an overflow check. Sometimes the checks are done manually; sometimes the array size is calculated with array_size() and sometimes by calculating n * size directly in code. Introduce wrappers for arrays for memdup_user() and vmemdup_user() to provide a standardized and safe way for duplicating user arrays. This is both for new code as well as replacing usage of (v)memdup_user() in existing code that uses, e.g., n * size to calculate array sizes. Suggested-by: David Airlie Signed-off-by: Philipp Stanner --- include/linux/string.h | 42 ++ 1 file changed, 42 insertions(+) diff --git a/include/linux/string.h b/include/linux/string.h index dbfc66400050..0e8e7a40bae7 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -6,6 +6,8 @@ #include/* for size_t */ #include /* for NULL */ #include/* for E2BIG */ +#include /* for check_mul_overflow() */ +#include /* for ERR_PTR() */ #include #include @@ -14,6 +16,46 @@ extern void *memdup_user(const void __user *, size_t); extern void *vmemdup_user(const void __user *, size_t); extern void *memdup_user_nul(const void __user *, size_t); +/** + * memdup_array_user - duplicate array from user space + * + * @src: source address in user space + * @n: number of array members to copy + * @size: size of one array member + * + * Return: an ERR_PTR() on failure. Result is physically + * contiguous, to be freed by kfree(). + */ +static inline void *memdup_array_user(const void __user *src, size_t n, size_t size) +{ + size_t nbytes; + + if (unlikely(check_mul_overflow(n, size, &nbytes))) + return ERR_PTR(-EINVAL); + + return memdup_user(src, nbytes); +} + +/** + * vmemdup_array_user - duplicate array from user space + * + * @src: source address in user space + * @n: number of array members to copy + * @size: size of one array member + * + * Return: an ERR_PTR() on failure. Result may be not + * physically contiguous. Use kvfree() to free. + */ +static inline void *vmemdup_array_user(const void __user *src, size_t n, size_t size) +{ + size_t nbytes; + + if (unlikely(check_mul_overflow(n, size, &nbytes))) + return ERR_PTR(-EINVAL); + + return vmemdup_user(src, nbytes); +} + /* * Include machine specific inline routines */ -- 2.41.0
[PATCH 2/5] kernel: kexec: copy user-array safely
Currently, there is no overflow-check with memdup_user(). Use the new function memdup_array_user() instead of memdup_user() for duplicating the user-space array safely. Suggested-by: David Airlie Signed-off-by: Philipp Stanner --- kernel/kexec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/kexec.c b/kernel/kexec.c index 92d301f98776..f6067c1bb089 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -242,7 +242,7 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments, ((flags & KEXEC_ARCH_MASK) != KEXEC_ARCH_DEFAULT)) return -EINVAL; - ksegments = memdup_user(segments, nr_segments * sizeof(ksegments[0])); + ksegments = memdup_array_user(segments, nr_segments, sizeof(ksegments[0])); if (IS_ERR(ksegments)) return PTR_ERR(ksegments); -- 2.41.0
[PATCH 3/5] kernel: watch_queue: copy user-array safely
Currently, there is no overflow-check with memdup_user(). Use the new function memdup_array_user() instead of memdup_user() for duplicating the user-space array safely. Suggested-by: David Airlie Signed-off-by: Philipp Stanner --- kernel/watch_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c index d0b6b390ee42..778b4056700f 100644 --- a/kernel/watch_queue.c +++ b/kernel/watch_queue.c @@ -331,7 +331,7 @@ long watch_queue_set_filter(struct pipe_inode_info *pipe, filter.__reserved != 0) return -EINVAL; - tf = memdup_user(_filter->filters, filter.nr_filters * sizeof(*tf)); + tf = memdup_array_user(_filter->filters, filter.nr_filters, sizeof(*tf)); if (IS_ERR(tf)) return PTR_ERR(tf); -- 2.41.0
[PATCH 4/5] drm_lease.c: copy user-array safely
Currently, there is no overflow-check with memdup_user(). Use the new function memdup_array_user() instead of memdup_user() for duplicating the user-space array safely. Suggested-by: David Airlie Signed-off-by: Philipp Stanner --- drivers/gpu/drm/drm_lease.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c index 150fe1555068..94375c6a5425 100644 --- a/drivers/gpu/drm/drm_lease.c +++ b/drivers/gpu/drm/drm_lease.c @@ -510,8 +510,8 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev, /* Handle leased objects, if any */ idr_init(&leases); if (object_count != 0) { - object_ids = memdup_user(u64_to_user_ptr(cl->object_ids), -array_size(object_count, sizeof(__u32))); + object_ids = memdup_array_user(u64_to_user_ptr(cl->object_ids), + object_count, sizeof(__u32)); if (IS_ERR(object_ids)) { ret = PTR_ERR(object_ids); idr_destroy(&leases); -- 2.41.0
[PATCH 5/5] drm: vmgfx_surface.c: copy user-array safely
Currently, there is no overflow-check with memdup_user(). Use the new function memdup_array_user() instead of memdup_user() for duplicating the user-space array safely. Suggested-by: David Airlie Signed-off-by: Philipp Stanner --- drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c index 5db403ee8261..9be185b094cb 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c @@ -777,9 +777,9 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, sizeof(metadata->mip_levels)); metadata->num_sizes = num_sizes; metadata->sizes = - memdup_user((struct drm_vmw_size __user *)(unsigned long) + memdup_array_user((struct drm_vmw_size __user *)(unsigned long) req->size_addr, - sizeof(*metadata->sizes) * metadata->num_sizes); + metadata->num_sizes, sizeof(*metadata->sizes)); if (IS_ERR(metadata->sizes)) { ret = PTR_ERR(metadata->sizes); goto out_no_sizes; -- 2.41.0
Re: [PATCH v2 04/15] drm/panthor: Add the device logical block
On Wed, 30 Aug 2023 14:17:57 +0100 Steven Price wrote: > >>> +static void panthor_device_reset_work(struct work_struct *work) > >>> +{ > >>> + struct panthor_device *ptdev = container_of(work, struct > >>> panthor_device, reset.work); > >>> + int ret, cookie; > >>> + > >>> + if (!drm_dev_enter(&ptdev->base, &cookie)) > >>> + return; > >>> + > >>> + panthor_sched_pre_reset(ptdev); > >>> + panthor_fw_pre_reset(ptdev, true); > >>> + panthor_mmu_pre_reset(ptdev); > >>> + panthor_gpu_soft_reset(ptdev); > >>> + panthor_gpu_l2_power_on(ptdev); > >>> + panthor_mmu_post_reset(ptdev); > >>> + ret = panthor_fw_post_reset(ptdev); > >>> + if (ret) > >>> + goto out; > >>> + > >>> + atomic_set(&ptdev->reset.pending, 0); > >>> + panthor_sched_post_reset(ptdev); > >>> + drm_dev_exit(cookie); > >>> + > >>> +out: > >>> + if (ret) { > >> > >> This looks like a race condition too - is there a need for a > >> drm_dev_exit_and_unplug() function? > > > > drm_dev_exit() is just releasing the read-lock. drm_dev_unplug() > > waits for all readers to be done and sets the unplugged value to true. > > So we only get readers/writer synchronization here, but nothing doing > > writer/writer sync. I guess the drm core leaves that to drivers, given > > drm_dev_unplug() is usually called from xxx_driver->remove() hook, on > > which serialization is guaranteed by the device-model. > > > > TLDR; yes, it's racy, but I don't think drm_dev_exit_and_unplug() would > > help solve the existing race. > > Yeah, I hadn't really thought through the reader/writer locks. > > > It's worth noting that we currently have only 2 paths calling > > panthor_device_unplug(): the platform_driver->remove() hook and the > > reset worker. Calling drm_dev_unplug() might not be the right thing to > > do, I just thought it was a good match to reflect the fact the device > > becomes inaccessible, without adding yet another kind of device-lost > > field. > > I quite liked the unplugged approach, it hides the complexities of the > GPU breaking nicely. > > However I do think this path needs fixing in some way, because of the > "goto out" we end up calling panthor_device_unplug() while in the > drm_dev_enter() section. Which, unless I'm mistaken, means > panthor_device_unplug() will call drm_dev_unplug() in that section - > which should produce a lockdep warning at the very least, if not an > actual deadlock. > > Given it's only a read lock - I think simply moving drm_dev_exit() below > the "out:" label fixes the deadlock without making any races worse. Oh, yeah, I didn't realize this is what you were complaining about. We definitely need to move the out label before drm_dev_exit(). > Whether the race here actually matters I'm not sure. It does if we want to be safe against removal. Maybe what we should do instead is synchronize the reset work in the platform->remove() path, and make sure it can't be scheduled after the synchronization happened. This way we don't have to worry about concurrent calls to panthor_device_unplug(), and we can keep the existing is_unplugged check. > >>> + > >>> +/** > >>> + * PANTHOR_IRQ_HANDLER() - Define interrupt handlers and the interrupt > >>> + * registration function. > >>> + * > >>> + * The boiler-plate to gracefully deal with shared interrupts is > >>> + * auto-generated. All you have to do is call PANTHOR_IRQ_HANDLER() > >>> + * just after you actual handler. The handler prototype is: > >> s/you/your/ or probably s/you/the/ since we don't expect people to be > >> adding more ;) > >> > >>> + * > >>> + * void (*handler)(struct panthor_device *, u32 status); > >>> + */ > >>> +#define PANTHOR_IRQ_HANDLER(__name, __reg_prefix, __handler) > >>> \ > >>> +static irqreturn_t panthor_ ## __name ## _irq_raw_handler(int irq, void > >>> *data) \ > >>> +{ > >>> \ > >>> + struct panthor_irq *pirq = data; > >>> \ > >>> + struct panthor_device *ptdev = pirq->ptdev; > >>> \ > >> > >> Maybe I'm missing something, but I was expecting a check here for if the > >> irq has been suspended and to avoid the register reads if it was. > > > > Thought the INT_MASK=0 + synchronize_irq() in panthor_xxx_irq_suspend() > > would guarantee that the handler can't be called after > > panthor_xxx_irq_suspend() was called. > > If the IRQ is shared then Linux doesn't know which device caused the > interrupt, so another device's (shared) interrupt could cause our > handler to be run. Uh, that's correct. We definitely need to check the ->suspended value before reading the register... > > >> Otherwise I'm not entirely sure I follow what all this code is for. > > > > Not entirely sure which code we're talking about. The reason we > > don't use the default raw IRQ handler
Re: [PATCH 1/5] string.h: add array-wrappers for (v)memdup_user()
On Wed, Aug 30, 2023 at 4:46 PM Philipp Stanner wrote: > > Currently, user array duplications are sometimes done without an > overflow check. Sometimes the checks are done manually; sometimes the > array size is calculated with array_size() and sometimes by calculating > n * size directly in code. > > Introduce wrappers for arrays for memdup_user() and vmemdup_user() to > provide a standardized and safe way for duplicating user arrays. > > This is both for new code as well as replacing usage of (v)memdup_user() > in existing code that uses, e.g., n * size to calculate array sizes. ... > --- a/include/linux/string.h > +++ b/include/linux/string.h I'm wondering if this has no side-effects as string.h/string.c IIRC is used also for early stages where some of the APIs are not available. > @@ -6,6 +6,8 @@ > #include/* for size_t */ > #include /* for NULL */ > #include/* for E2BIG */ > +#include /* for check_mul_overflow() */ > +#include /* for ERR_PTR() */ Can we preserve order (to some extent)? > #include > #include ... > +/** > + * memdup_array_user - duplicate array from user space > + * Do we need this blank line? > + * @src: source address in user space > + * @n: number of array members to copy > + * @size: size of one array member > + * > + * Return: an ERR_PTR() on failure. Result is physically > + * contiguous, to be freed by kfree(). > + */ ... > +/** > + * vmemdup_array_user - duplicate array from user space > + * Redundant? > + * @src: source address in user space > + * @n: number of array members to copy > + * @size: size of one array member > + * > + * Return: an ERR_PTR() on failure. Result may be not > + * physically contiguous. Use kvfree() to free. > + */ -- With Best Regards, Andy Shevchenko
Re: [PATCH v2 08/15] drm/panthor: Add the MMU/VM logical block
On 29/08/2023 16:33, Boris Brezillon wrote: > On Mon, 14 Aug 2023 16:53:09 +0100 > Steven Price wrote: > >>> + >>> +/** >>> + * struct panthor_vm_op_ctx - VM operation context >>> + * >>> + * With VM operations potentially taking place in a dma-signaling path, we >>> + * need to make sure everything that might require resource allocation is >>> + * pre-allocated upfront. This is what this operation context is far. >>> + * >>> + * We also collect resources that have been freed, so we can release them >>> + * asynchronously, and let the VM_BIND scheduler process the next VM_BIND >>> + * request. >>> + */ >>> +struct panthor_vm_op_ctx { >>> + /** @rsvd_page_tables: Pages reserved for the MMU page table update. */ >>> + struct { >>> + /** @count: Number of pages reserved. */ >>> + u32 count; >>> + >>> + /** @ptr: Point to the first unused page in the @pages table. */ >>> + u32 ptr; >>> + >>> + /** >>> +* @page: Array of pages that can be used for an MMU page table >>> update. >>> +* >>> +* After an VM operation, there might be free pages left in >>> this array. >>> +* They should be returned to the pt_cache as part of the >>> op_ctx cleanup. >>> +*/ >>> + void **pages; >>> + } rsvd_page_tables; >> >> Two questions: >> >> 1) Would a mempool simplify the implementation? It looks like a >> reasonable match. > > Not sure what you mean by mempool, See include/linux/mempool.h > but I'm using a kmem_cache here for > all page table allocations. The pages that are passed to > panthor_vm_op_ctx::rsvd_page_tables::pages are allocated from this > pool. It's just that for each VM operation we pre-allocate page-tables, > and release those that were not used when the operation is done (we > over-allocate for the worst case scenario). The mempool could, potentially, replace the rsvd_page_tables structure. The kmem_cache you would still want as that's per-driver. >> >> 2) Does it really make sense to have a separate pool of memory for every >> operation? Instead of having a separate pool for each operation, it >> would be possible to just keep track of the total number needed for all >> outstanding operations. Then a single (per device or maybe per-VM if >> necessary) mempool could be resized to ensure it has the right amount of >> space. > > The pool is per-driver (see the global pt_cache). rsvd_page_tables just > holds pages needed for a specific VM operation. To be more specific, it > holds pages for the worst case (page table tree is empty, except for the > root page table). What I'm wondering is to we need to keep the pages for each operation in separate pools. So instead of having a rsvd_page_tables for each operation, can we have one global one which is sized appropriately for all operations that are in flight for the device? The operations are serialized so there's no contention. Or at least a per-VM pool if we can operate on multiple VMs at once. >> >> I'm also a little wary that the VM_BIND infrastructure could potentially >> be abused to trigger a large amount of kernel allocation as it allocates >> up-front for the worst case but those pages are not charged to the >> process (AFAICT). But I haven't fully got my head round that yet. > > Yep, that's problematic, indeed. I considered allocating page tables > as GEM objects, but the overhead of a GEM object is quite big > (hundreds of bytes of meta-data) compared to the size of a page table > (4k), and kmem_cache was just super convenient for this page table > cache :-). I think page tables as GEM objects is likely to be overkill, we obviously also have to be careful not to allow user space to get access to the contents - whereas GEM objects are usually to provide user space access ;) I'm not sure quite what the best solution here is, clearly one 'solution' is to just cap the number of outstanding VM_BINDs. >> >>> + >>> + /** @flags: Combination of drm_panthor_vm_bind_op_flags. */ >>> + u32 flags; >>> + >>> + /** @va: Virtual range targeted by the VM operation. */ >>> + struct { >>> + /** @addr: Start address. */ >>> + u64 addr; >>> + >>> + /** @range: Range size. */ >>> + u64 range; >>> + } va; >>> + >>> + /** >>> +* @returned_vmas: List of panthor_vma objects returned after a VM >>> operation. >>> +* >>> +* For unmap operations, this will contain all VMAs that were covered >>> by the >>> +* specified VA range. >>> +* >>> +* For map operations, this will contain all VMAs that previously >>> mapped to >>> +* the specified VA range. >>> +* >>> +* Those VMAs, and the resources they point to will be released as part >>> of >>> +* the op_ctx cleanup operation. >>> +*/ >>> + struct list_head returned_vmas; >>> + >>> + /** @map: Fields specific to a map operation. */ >>> + struct { >>> + /** @gem: GEM object information
Re: [PATCH 1/5] string.h: add array-wrappers for (v)memdup_user()
On Wed, Aug 30, 2023 at 4:46 PM Philipp Stanner wrote: > + if (unlikely(check_mul_overflow(n, size, &nbytes))) > + return ERR_PTR(-EINVAL); > + if (unlikely(check_mul_overflow(n, size, &nbytes))) > + return ERR_PTR(-EINVAL); Btw, why not -EOVERFLOW ? -- With Best Regards, Andy Shevchenko
Re: [PATCH 1/5] string.h: add array-wrappers for (v)memdup_user()
On Wed, 2023-08-30 at 17:11 +0300, Andy Shevchenko wrote: > On Wed, Aug 30, 2023 at 4:46 PM Philipp Stanner > wrote: > > > > Currently, user array duplications are sometimes done without an > > overflow check. Sometimes the checks are done manually; sometimes > > the > > array size is calculated with array_size() and sometimes by > > calculating > > n * size directly in code. > > > > Introduce wrappers for arrays for memdup_user() and vmemdup_user() > > to > > provide a standardized and safe way for duplicating user arrays. > > > > This is both for new code as well as replacing usage of > > (v)memdup_user() > > in existing code that uses, e.g., n * size to calculate array > > sizes. > > ... > > > --- a/include/linux/string.h > > +++ b/include/linux/string.h > > I'm wondering if this has no side-effects as string.h/string.c IIRC > is > used also for early stages where some of the APIs are not available. > > > @@ -6,6 +6,8 @@ > > #include /* for size_t */ > > #include /* for NULL */ > > #include /* for E2BIG */ > > +#include /* for check_mul_overflow() */ > > +#include /* for ERR_PTR() */ > > Can we preserve order (to some extent)? Sure. I just put it there so the comments build a congruent block. Which order would you prefer? > > > #include > > #include > > ... > > > +/** > > + * memdup_array_user - duplicate array from user space > > > + * > > Do we need this blank line? I more or less directly copied the docstring format from the original functions (v)memdup_user() in mm/util.c I guess this is common style? > > > + * @src: source address in user space > > + * @n: number of array members to copy > > + * @size: size of one array member > > + * > > + * Return: an ERR_PTR() on failure. Result is physically > > + * contiguous, to be freed by kfree(). > > + */ > > ... > > > +/** > > + * vmemdup_array_user - duplicate array from user space > > > + * > > Redundant? No, there are two functions: * memdup_array_user() * vmemdup_array_user() On the deeper layers they utilize kmalloc() or kvmalloc(), respectively. Greetings, P. > > > + * @src: source address in user space > > + * @n: number of array members to copy > > + * @size: size of one array member > > + * > > + * Return: an ERR_PTR() on failure. Result may be not > > + * physically contiguous. Use kvfree() to free. > > + */ >
Re: [PATCH 1/5] drm/debugfs: drop debugfs_init() for the render and accel node v2
Am 30.08.23 um 10:19 schrieb Andi Shyti: Hi Christian, On Tue, Aug 29, 2023 at 01:01:11PM +0200, Christian König wrote: We want to remove per minor debugfs directories. Start by stopping drivers from adding anything inside of those in the mid layer callback. v2: drop it for the accel node as well Signed-off-by: Christian König Tested-by: Stanislaw Gruszka Reviewed-by: Andi Shyti Is that for just this patch or the whole series? Thanks, Christian. Thanks, Andi
Re: [PATCH 1/5] string.h: add array-wrappers for (v)memdup_user()
On Wed, 2023-08-30 at 17:15 +0300, Andy Shevchenko wrote: > On Wed, Aug 30, 2023 at 4:46 PM Philipp Stanner > wrote: > > > + if (unlikely(check_mul_overflow(n, size, &nbytes))) > > + return ERR_PTR(-EINVAL); > > > + if (unlikely(check_mul_overflow(n, size, &nbytes))) > > + return ERR_PTR(-EINVAL); > > Btw, why not -EOVERFLOW ? > Good question, actually. To be honest I wasn't quite sure which code to pick (-E2BIG was also once I candidate). -EINVAL was picked because the idea was that a request overflowing a size_t could surely be expected to contain an invalid parameter, because no one would ever request an array _that_ large ?
[PATCH v2 0/8] ADV7511 driver enhancements
This patch series aims to improve ADV7511 driver by adding feature bits and data instead of comparing enum adv7511_type for various hardware differences between ADV7511, ADV7533 and ADV7535. This patch series tested with[1] on RZ/G2L SMARC EVK which embeds ADV7535. [1] https://patchwork.kernel.org/project/linux-renesas-soc/list/?series=762260 v1->v2: * Added Rb tag from Adam and Laurent. * Added tested by tag from Adam and Fabio. * Updated commit description with reason *why* the change is needed. * Dropped the local info variable and instead started using adv7511->info->type in probe(). * Replaced max_mode_clock->max_mode_clock_khz in struct adv7511_chip_info * Replaced variable type for max_mode_clock_khz from unsigned int->unsigned long. * Replaced max_lane_freq->max_lane_freq_khz in struct adv7511_chip_info. * Replaced max_lane_freq_khz variable type from unsigned long->unsigned int. * Added trailing commas for num_supplies in adv753{3,5}_chip_info. * Added patch#5 for adding the reg_cec_offset variable to struct adv7511_chip_info. * Replaced has_dsi variable type from unsigned->bool. * Restored check using type for low_refresh_rate and regmap_register_patch(). * Replaced link_config variable type from unsigned->bool. * Restored enum adv7511_type as there are users. * Replaced hpd_override_enable variable type from unsigned->bool. Biju Das (8): drm: adv7511: Add struct adv7511_chip_info and use i2c_get_match_data() drm: adv7511: Add max_mode_clock_khz variable to struct adv7511_chip_info drm: adv7511: Add max_lane_freq_khz variable to struct adv7511_chip_info drm: adv7511: Add supply_names and num_supplies variables to struct adv7511_chip_info drm: adv7511: Add reg_cec_offset variable to struct adv7511_chip_info drm: adv7511: Add has_dsi variable to struct adv7511_chip_info drm: adv7511: Add link_config variable to struct adv7511_chip_info drm: adv7511: Add hpd_override_enable variable to struct adv7511_chip_info drivers/gpu/drm/bridge/adv7511/adv7511.h | 16 ++- drivers/gpu/drm/bridge/adv7511/adv7511_cec.c | 14 +-- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 104 +++ drivers/gpu/drm/bridge/adv7511/adv7533.c | 7 +- 4 files changed, 81 insertions(+), 60 deletions(-) -- 2.25.1
[PATCH v2 1/8] drm: adv7511: Add struct adv7511_chip_info and use i2c_get_match_data()
Add struct adv7511_chip_info to handle hw differences between various chips rather checking against the 'type' variable in various places. Replace 'adv->type'->'info->type' by moving variable 'type' from struct adv7511 to struct adv7511_chip_info and add adv7511_chip_info as device data for both OF and ID tables instead of the device type. Simplify the probe() by replacing of_device_get_match_data() and ID lookup for retrieving match data with i2c_get_match_data(). Signed-off-by: Biju Das Tested-by: Fabio Estevam Reviewed-by: Adam Ford Reviewed-by: Laurent Pinchart --- v1->v2: * Added Tested by tag from Fabio Estevam. * Added Rb tag from Adam and Laurent. * Updated commit description with reason *why* the change is needed. * Dropped the local info variable and instead started using adv7511->info->type in probe(). --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 6 +- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 65 +++- drivers/gpu/drm/bridge/adv7511/adv7533.c | 4 +- 3 files changed, 43 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index 17445800248d..59e8ef10d72e 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -333,6 +333,10 @@ enum adv7511_type { #define ADV7511_MAX_ADDRS 3 +struct adv7511_chip_info { + enum adv7511_type type; +}; + struct adv7511 { struct i2c_client *i2c_main; struct i2c_client *i2c_edid; @@ -377,7 +381,7 @@ struct adv7511 { u8 num_dsi_lanes; bool use_timing_gen; - enum adv7511_type type; + const struct adv7511_chip_info *info; struct platform_device *audio_pdev; struct cec_adapter *cec_adap; diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 2611afd2c1c1..d869dbe41873 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -354,7 +354,7 @@ static void __adv7511_power_on(struct adv7511 *adv7511) * first few seconds after enabling the output. On the other hand * adv7535 require to enable HPD Override bit for proper HPD. */ - if (adv7511->type == ADV7535) + if (adv7511->info->type == ADV7535) regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, ADV7535_REG_POWER2_HPD_OVERRIDE, ADV7535_REG_POWER2_HPD_OVERRIDE); @@ -373,7 +373,7 @@ static void adv7511_power_on(struct adv7511 *adv7511) */ regcache_sync(adv7511->regmap); - if (adv7511->type == ADV7533 || adv7511->type == ADV7535) + if (adv7511->info->type == ADV7533 || adv7511->info->type == ADV7535) adv7533_dsi_power_on(adv7511); adv7511->powered = true; } @@ -381,7 +381,7 @@ static void adv7511_power_on(struct adv7511 *adv7511) static void __adv7511_power_off(struct adv7511 *adv7511) { /* TODO: setup additional power down modes */ - if (adv7511->type == ADV7535) + if (adv7511->info->type == ADV7535) regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, ADV7535_REG_POWER2_HPD_OVERRIDE, 0); @@ -397,7 +397,7 @@ static void __adv7511_power_off(struct adv7511 *adv7511) static void adv7511_power_off(struct adv7511 *adv7511) { __adv7511_power_off(adv7511); - if (adv7511->type == ADV7533 || adv7511->type == ADV7535) + if (adv7511->info->type == ADV7533 || adv7511->info->type == ADV7535) adv7533_dsi_power_off(adv7511); adv7511->powered = false; } @@ -682,7 +682,7 @@ adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector) status = connector_status_disconnected; } else { /* Renable HPD sensing */ - if (adv7511->type == ADV7535) + if (adv7511->info->type == ADV7535) regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, ADV7535_REG_POWER2_HPD_OVERRIDE, ADV7535_REG_POWER2_HPD_OVERRIDE); @@ -786,7 +786,7 @@ static void adv7511_mode_set(struct adv7511 *adv7511, else low_refresh_rate = ADV7511_LOW_REFRESH_RATE_NONE; - if (adv7511->type == ADV7511) + if (adv7511->info->type == ADV7511) regmap_update_bits(adv7511->regmap, 0xfb, 0x6, low_refresh_rate << 1); else @@ -921,7 +921,7 @@ static enum drm_mode_status adv7511_bridge_mode_valid(struct drm_bridge *bridge, { struct adv7511 *adv = bridge_to_adv7511(bridge); - if (adv->type == ADV7533 || adv->type == ADV7535) + if (adv->info->type == ADV7533 || adv->info->type == ADV7535) return adv7533_mode_valid(adv,
[PATCH v2 2/8] drm: adv7511: Add max_mode_clock_khz variable to struct adv7511_chip_info
The ADV7533 supports a maximum pixel clock of 80MHz whereas it is 148.5MHz for ADV7535. Add max_mode_clock_khz variable to struct adv7511_chip_info to handle this difference. Signed-off-by: Biju Das Reviewed-by: Adam Ford Tested-by: Adam Ford #imx8mm-beacon Reviewed-by: Laurent Pinchart --- * Added Rb tag from Adam and Laurent * Added tested by tag from Adam. * Replaced max_mode_clock->max_mode_clock_khz in struct adv7511_chip_info * Replaced variable type from unsigned int->unsigned long. --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 + drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 2 ++ drivers/gpu/drm/bridge/adv7511/adv7533.c | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index 59e8ef10d72e..b9c6c1e8a353 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -335,6 +335,7 @@ enum adv7511_type { struct adv7511_chip_info { enum adv7511_type type; + unsigned int max_mode_clock_khz; }; struct adv7511 { diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index d869dbe41873..12ceffd6a9eb 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -1369,10 +1369,12 @@ static const struct adv7511_chip_info adv7511_chip_info = { static const struct adv7511_chip_info adv7533_chip_info = { .type = ADV7533, + .max_mode_clock_khz = 8, }; static const struct adv7511_chip_info adv7535_chip_info = { .type = ADV7535, + .max_mode_clock_khz = 148500, }; static const struct i2c_device_id adv7511_i2c_ids[] = { diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c b/drivers/gpu/drm/bridge/adv7511/adv7533.c index c452c4dc1c3f..1d113489754c 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7533.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c @@ -108,7 +108,7 @@ enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv, u8 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); /* Check max clock for either 7533 or 7535 */ - if (mode->clock > (adv->info->type == ADV7533 ? 8 : 148500)) + if (mode->clock > adv->info->max_mode_clock_khz) return MODE_CLOCK_HIGH; /* Check max clock for each lane */ -- 2.25.1
[PATCH v2 3/8] drm: adv7511: Add max_lane_freq_khz variable to struct adv7511_chip_info
The ADV7533 supports a maximum lane clock of 800MHz whereas it is 891MHz for ADV7535. Add max_lane_freq_khz variable to struct adv7511_chip_info to handle this difference. While at it, drop the unused local variable max_lane_freq. Signed-off-by: Biju Das Reviewed-by: Laurent Pinchart --- v1->v2: * Added Rb tag from Laurent. * Replaced max_lane_freq->max_lane_freq_khz in struct adv7511_chip_info. * Replaced variable type from unsigned long->unsigned int. --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 + drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 2 ++ drivers/gpu/drm/bridge/adv7511/adv7533.c | 5 + 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index b9c6c1e8a353..f8d61f2fa30e 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -336,6 +336,7 @@ enum adv7511_type { struct adv7511_chip_info { enum adv7511_type type; unsigned int max_mode_clock_khz; + unsigned int max_lane_freq_khz; }; struct adv7511 { diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 12ceffd6a9eb..1c76aa5a5d5b 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -1370,11 +1370,13 @@ static const struct adv7511_chip_info adv7511_chip_info = { static const struct adv7511_chip_info adv7533_chip_info = { .type = ADV7533, .max_mode_clock_khz = 8, + .max_lane_freq_khz = 80, }; static const struct adv7511_chip_info adv7535_chip_info = { .type = ADV7535, .max_mode_clock_khz = 148500, + .max_lane_freq_khz = 891000, }; static const struct i2c_device_id adv7511_i2c_ids[] = { diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c b/drivers/gpu/drm/bridge/adv7511/adv7533.c index 1d113489754c..4481489aaf5e 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7533.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c @@ -103,7 +103,6 @@ void adv7533_dsi_power_off(struct adv7511 *adv) enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv, const struct drm_display_mode *mode) { - unsigned long max_lane_freq; struct mipi_dsi_device *dsi = adv->dsi; u8 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); @@ -112,9 +111,7 @@ enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv, return MODE_CLOCK_HIGH; /* Check max clock for each lane */ - max_lane_freq = (adv->info->type == ADV7533 ? 80 : 891000); - - if (mode->clock * bpp > max_lane_freq * adv->num_dsi_lanes) + if (mode->clock * bpp > adv->info->max_lane_freq_khz * adv->num_dsi_lanes) return MODE_CLOCK_HIGH; return MODE_OK; -- 2.25.1
[PATCH v2 4/8] drm: adv7511: Add supply_names and num_supplies variables to struct adv7511_chip_info
The ADV7511 has 5 power supplies compared to 7 that of ADV75{33,35}. Add supply_names and num_supplies variables to struct adv7511_chip_info to handle this difference. Signed-off-by: Biju Das Reviewed-by: Laurent Pinchart --- v1->v2: * Added Rb tag from Laurent. * Added trailing commas for num_supplies in adv753{3,5}_chip_info. --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 3 ++- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 27 ++-- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index f8d61f2fa30e..edf7be9c21d3 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -337,6 +337,8 @@ struct adv7511_chip_info { enum adv7511_type type; unsigned int max_mode_clock_khz; unsigned int max_lane_freq_khz; + const char * const *supply_names; + unsigned int num_supplies; }; struct adv7511 { @@ -375,7 +377,6 @@ struct adv7511 { struct gpio_desc *gpio_pd; struct regulator_bulk_data *supplies; - unsigned int num_supplies; /* ADV7533 DSI RX related params */ struct device_node *host_node; diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 1c76aa5a5d5b..2bcd17953221 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -1004,37 +1004,30 @@ static const char * const adv7533_supply_names[] = { static int adv7511_init_regulators(struct adv7511 *adv) { + const char * const *supply_names = adv->info->supply_names; + unsigned int num_supplies = adv->info->num_supplies; struct device *dev = &adv->i2c_main->dev; - const char * const *supply_names; unsigned int i; int ret; - if (adv->info->type == ADV7511) { - supply_names = adv7511_supply_names; - adv->num_supplies = ARRAY_SIZE(adv7511_supply_names); - } else { - supply_names = adv7533_supply_names; - adv->num_supplies = ARRAY_SIZE(adv7533_supply_names); - } - - adv->supplies = devm_kcalloc(dev, adv->num_supplies, + adv->supplies = devm_kcalloc(dev, num_supplies, sizeof(*adv->supplies), GFP_KERNEL); if (!adv->supplies) return -ENOMEM; - for (i = 0; i < adv->num_supplies; i++) + for (i = 0; i < num_supplies; i++) adv->supplies[i].supply = supply_names[i]; - ret = devm_regulator_bulk_get(dev, adv->num_supplies, adv->supplies); + ret = devm_regulator_bulk_get(dev, num_supplies, adv->supplies); if (ret) return ret; - return regulator_bulk_enable(adv->num_supplies, adv->supplies); + return regulator_bulk_enable(num_supplies, adv->supplies); } static void adv7511_uninit_regulators(struct adv7511 *adv) { - regulator_bulk_disable(adv->num_supplies, adv->supplies); + regulator_bulk_disable(adv->info->num_supplies, adv->supplies); } static bool adv7511_cec_register_volatile(struct device *dev, unsigned int reg) @@ -1365,18 +1358,24 @@ static void adv7511_remove(struct i2c_client *i2c) static const struct adv7511_chip_info adv7511_chip_info = { .type = ADV7511, + .supply_names = adv7511_supply_names, + .num_supplies = ARRAY_SIZE(adv7511_supply_names), }; static const struct adv7511_chip_info adv7533_chip_info = { .type = ADV7533, .max_mode_clock_khz = 8, .max_lane_freq_khz = 80, + .supply_names = adv7533_supply_names, + .num_supplies = ARRAY_SIZE(adv7533_supply_names), }; static const struct adv7511_chip_info adv7535_chip_info = { .type = ADV7535, .max_mode_clock_khz = 148500, .max_lane_freq_khz = 891000, + .supply_names = adv7533_supply_names, + .num_supplies = ARRAY_SIZE(adv7533_supply_names), }; static const struct i2c_device_id adv7511_i2c_ids[] = { -- 2.25.1
[PATCH v2 5/8] drm: adv7511: Add reg_cec_offset variable to struct adv7511_chip_info
The ADV7533 and ADV7535 have an offset(0x70) for the CEC register map compared to ADV7511. Add the reg_cec_offset variable to struct adv7511_chip_info to handle this difference and drop the reg_cec_offset variable from struct adv7511. This will avoid assigning reg_cec_offset based on chip type and also testing for multiple chip types for calling adv7533_patch_cec_registers(). Signed-off-by: Biju Das --- v2: * New patch. --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 2 +- drivers/gpu/drm/bridge/adv7511/adv7511_cec.c | 14 +++--- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 8 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index edf7be9c21d3..a728bfb33d03 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -339,6 +339,7 @@ struct adv7511_chip_info { unsigned int max_lane_freq_khz; const char * const *supply_names; unsigned int num_supplies; + unsigned int reg_cec_offset; }; struct adv7511 { @@ -349,7 +350,6 @@ struct adv7511 { struct regmap *regmap; struct regmap *regmap_cec; - unsigned int reg_cec_offset; enum drm_connector_status status; bool powered; diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c index 2a6b91f752cb..44451a9658a3 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c @@ -33,7 +33,7 @@ static const u8 ADV7511_REG_CEC_RX_FRAME_LEN[] = { static void adv_cec_tx_raw_status(struct adv7511 *adv7511, u8 tx_raw_status) { - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; unsigned int val; if (regmap_read(adv7511->regmap_cec, @@ -84,7 +84,7 @@ static void adv_cec_tx_raw_status(struct adv7511 *adv7511, u8 tx_raw_status) static void adv7511_cec_rx(struct adv7511 *adv7511, int rx_buf) { - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; struct cec_msg msg = {}; unsigned int len; unsigned int val; @@ -121,7 +121,7 @@ static void adv7511_cec_rx(struct adv7511 *adv7511, int rx_buf) void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1) { - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; const u32 irq_tx_mask = ADV7511_INT1_CEC_TX_READY | ADV7511_INT1_CEC_TX_ARBIT_LOST | ADV7511_INT1_CEC_TX_RETRY_TIMEOUT; @@ -177,7 +177,7 @@ void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1) static int adv7511_cec_adap_enable(struct cec_adapter *adap, bool enable) { struct adv7511 *adv7511 = cec_get_drvdata(adap); - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; if (adv7511->i2c_cec == NULL) return -EIO; @@ -223,7 +223,7 @@ static int adv7511_cec_adap_enable(struct cec_adapter *adap, bool enable) static int adv7511_cec_adap_log_addr(struct cec_adapter *adap, u8 addr) { struct adv7511 *adv7511 = cec_get_drvdata(adap); - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; unsigned int i, free_idx = ADV7511_MAX_ADDRS; if (!adv7511->cec_enabled_adap) @@ -292,7 +292,7 @@ static int adv7511_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, u32 signal_free_time, struct cec_msg *msg) { struct adv7511 *adv7511 = cec_get_drvdata(adap); - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; u8 len = msg->len; unsigned int i; @@ -345,7 +345,7 @@ static int adv7511_cec_parse_dt(struct device *dev, struct adv7511 *adv7511) int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511) { - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; int ret = adv7511_cec_parse_dt(dev, adv7511); if (ret) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 2bcd17953221..d806c870bf76 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -1035,7 +1035,7 @@ static bool adv7511_cec_register_volatile(struct device *dev, unsigned int reg) struct i2c_client *i2c = to_i2c_client(dev); struct adv7511 *adv7511 = i2c_get_clientdata(i2c); - reg -= adv7511->reg_cec_offset; + reg -= adv7511->info->reg_cec_offset; switch (reg) { case ADV7511_REG_CEC_RX1_FRAME_HDR: @@
[PATCH v2 6/8] drm: adv7511: Add has_dsi variable to struct adv7511_chip_info
The ADV7533 and ADV7535 have DSI support. Add a variable has_dsi to struct adv7511_chip_info for handling configuration related to DSI. Signed-off-by: Biju Das --- v1->v2: * Replaced variable type from unsigned->bool. * Restored check using type for low_refresh_rate and regmap_register_patch(). --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 + drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 10 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index a728bfb33d03..0dd56e311039 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -340,6 +340,7 @@ struct adv7511_chip_info { const char * const *supply_names; unsigned int num_supplies; unsigned int reg_cec_offset; + bool has_dsi; }; struct adv7511 { diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index d806c870bf76..9d88c29b6f59 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -373,7 +373,7 @@ static void adv7511_power_on(struct adv7511 *adv7511) */ regcache_sync(adv7511->regmap); - if (adv7511->info->type == ADV7533 || adv7511->info->type == ADV7535) + if (adv7511->info->has_dsi) adv7533_dsi_power_on(adv7511); adv7511->powered = true; } @@ -397,7 +397,7 @@ static void __adv7511_power_off(struct adv7511 *adv7511) static void adv7511_power_off(struct adv7511 *adv7511) { __adv7511_power_off(adv7511); - if (adv7511->info->type == ADV7533 || adv7511->info->type == ADV7535) + if (adv7511->info->has_dsi) adv7533_dsi_power_off(adv7511); adv7511->powered = false; } @@ -921,7 +921,7 @@ static enum drm_mode_status adv7511_bridge_mode_valid(struct drm_bridge *bridge, { struct adv7511 *adv = bridge_to_adv7511(bridge); - if (adv->info->type == ADV7533 || adv->info->type == ADV7535) + if (adv->info->has_dsi) return adv7533_mode_valid(adv, mode); else return adv7511_mode_valid(adv, mode); @@ -1311,7 +1311,7 @@ static int adv7511_probe(struct i2c_client *i2c) adv7511_audio_init(dev, adv7511); - if (adv7511->info->type == ADV7533 || adv7511->info->type == ADV7535) { + if (adv7511->info->has_dsi) { ret = adv7533_attach_dsi(adv7511); if (ret) goto err_unregister_audio; @@ -1367,6 +1367,7 @@ static const struct adv7511_chip_info adv7533_chip_info = { .supply_names = adv7533_supply_names, .num_supplies = ARRAY_SIZE(adv7533_supply_names), .reg_cec_offset = ADV7533_REG_CEC_OFFSET, + .has_dsi = true, }; static const struct adv7511_chip_info adv7535_chip_info = { @@ -1376,6 +1377,7 @@ static const struct adv7511_chip_info adv7535_chip_info = { .supply_names = adv7533_supply_names, .num_supplies = ARRAY_SIZE(adv7533_supply_names), .reg_cec_offset = ADV7533_REG_CEC_OFFSET, + .has_dsi = true, }; static const struct i2c_device_id adv7511_i2c_ids[] = { -- 2.25.1
[PATCH v2 7/8] drm: adv7511: Add link_config variable to struct adv7511_chip_info
The ADV7511 needs link configuration whereas ADV75{33,35} does not need it. Add a variable link_config to struct adv7511_chip_info to handle this difference. Signed-off-by: Biju Das Reviewed-by: Laurent Pinchart --- v1->v2: * Add Rb tag from Laurent. * Replaced variable type from unsigned->bool. --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 + drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index 0dd56e311039..0d39e32b0793 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -341,6 +341,7 @@ struct adv7511_chip_info { unsigned int num_supplies; unsigned int reg_cec_offset; bool has_dsi; + bool link_config; }; struct adv7511 { diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 9d88c29b6f59..e0ec3c098225 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -1203,7 +1203,7 @@ static int adv7511_probe(struct i2c_client *i2c) memset(&link_config, 0, sizeof(link_config)); - if (adv7511->info->type == ADV7511) + if (adv7511->info->link_config) ret = adv7511_parse_dt(dev->of_node, &link_config); else ret = adv7533_parse_dt(dev->of_node, adv7511); @@ -1292,7 +1292,7 @@ static int adv7511_probe(struct i2c_client *i2c) i2c_set_clientdata(i2c, adv7511); - if (adv7511->info->type == ADV7511) + if (adv7511->info->link_config) adv7511_set_link_config(adv7511, &link_config); ret = adv7511_cec_init(dev, adv7511); @@ -1358,6 +1358,7 @@ static const struct adv7511_chip_info adv7511_chip_info = { .type = ADV7511, .supply_names = adv7511_supply_names, .num_supplies = ARRAY_SIZE(adv7511_supply_names), + .link_config = true, }; static const struct adv7511_chip_info adv7533_chip_info = { -- 2.25.1
[PATCH v2 8/8] drm: adv7511: Add hpd_override_enable variable to struct adv7511_chip_info
As per spec, it is allowed to pulse the HPD signal to indicate that the EDID information has changed. Some monitors do this when they wake up from standby or are enabled. When the HPD goes low the adv7511 is reset and the outputs are disabled which might cause the monitor to go to standby again. To avoid this we ignore the HPD pin for the first few seconds after enabling the output. On the other hand, adv7535 require to enable HPD Override bit for proper HPD. Add hpd_override_enable variable to struct adv7511_chip_info to handle this scenario. Signed-off-by: Biju Das --- v1->v2: * Restored enum adv7511_type as there are users. * Replaced variable type from unsigned->bool. --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 + drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 7 --- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index 0d39e32b0793..39c9ece373b0 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -342,6 +342,7 @@ struct adv7511_chip_info { unsigned int reg_cec_offset; bool has_dsi; bool link_config; + bool hpd_override_enable; }; struct adv7511 { diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index e0ec3c098225..83ff4206b3b7 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -354,7 +354,7 @@ static void __adv7511_power_on(struct adv7511 *adv7511) * first few seconds after enabling the output. On the other hand * adv7535 require to enable HPD Override bit for proper HPD. */ - if (adv7511->info->type == ADV7535) + if (adv7511->info->hpd_override_enable) regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, ADV7535_REG_POWER2_HPD_OVERRIDE, ADV7535_REG_POWER2_HPD_OVERRIDE); @@ -381,7 +381,7 @@ static void adv7511_power_on(struct adv7511 *adv7511) static void __adv7511_power_off(struct adv7511 *adv7511) { /* TODO: setup additional power down modes */ - if (adv7511->info->type == ADV7535) + if (adv7511->info->hpd_override_enable) regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, ADV7535_REG_POWER2_HPD_OVERRIDE, 0); @@ -682,7 +682,7 @@ adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector) status = connector_status_disconnected; } else { /* Renable HPD sensing */ - if (adv7511->info->type == ADV7535) + if (adv7511->info->hpd_override_enable) regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, ADV7535_REG_POWER2_HPD_OVERRIDE, ADV7535_REG_POWER2_HPD_OVERRIDE); @@ -1379,6 +1379,7 @@ static const struct adv7511_chip_info adv7535_chip_info = { .num_supplies = ARRAY_SIZE(adv7533_supply_names), .reg_cec_offset = ADV7533_REG_CEC_OFFSET, .has_dsi = true, + .hpd_override_enable = true, }; static const struct i2c_device_id adv7511_i2c_ids[] = { -- 2.25.1
Re: [PATCH 1/5] string.h: add array-wrappers for (v)memdup_user()
On Wed, Aug 30, 2023 at 5:19 PM wrote: > On Wed, 2023-08-30 at 17:11 +0300, Andy Shevchenko wrote: > > On Wed, Aug 30, 2023 at 4:46 PM Philipp Stanner > > wrote: > > > --- a/include/linux/string.h > > > +++ b/include/linux/string.h > > > > I'm wondering if this has no side-effects as string.h/string.c IIRC > > is > > used also for early stages where some of the APIs are not available. > > > > > @@ -6,6 +6,8 @@ > > > #include/* for size_t */ > > > #include /* for NULL */ > > > #include/* for E2BIG */ > > > +#include /* for check_mul_overflow() */ > > > +#include /* for ERR_PTR() */ > > > > Can we preserve order (to some extent)? > > Sure. I just put it there so the comments build a congruent block. > Which order would you prefer? Alphabetical. compiler.h err.h overflow.h ...the rest that is a bit unordered... > > > #include > > > #include ... > > > +/** > > > + * memdup_array_user - duplicate array from user space > > > > > + * > > > > Do we need this blank line? > > I more or less directly copied the docstring format from the original > functions (v)memdup_user() in mm/util.c > I guess this is common style? I think it's not. But you may grep kernel source tree and tell which one occurs more often with or without this (unneeded) blank line. > > > + * @src: source address in user space > > > + * @n: number of array members to copy > > > + * @size: size of one array member > > > + * > > > + * Return: an ERR_PTR() on failure. Result is physically > > > + * contiguous, to be freed by kfree(). > > > + */ ... > > > +/** > > > + * vmemdup_array_user - duplicate array from user space > > > > > + * > > > > Redundant? > > No, there are two functions: > * memdup_array_user() > * vmemdup_array_user() > > On the deeper layers they utilize kmalloc() or kvmalloc(), > respectively. I guess you misunderstood my comment. I was talking about kernel doc (as in the previous function). > > > + * @src: source address in user space > > > + * @n: number of array members to copy > > > + * @size: size of one array member > > > + * > > > + * Return: an ERR_PTR() on failure. Result may be not > > > + * physically contiguous. Use kvfree() to free. > > > + */ -- With Best Regards, Andy Shevchenko
Re: [PATCH v11] drm: Add initial ci/ subdirectory
replying to a couple points on this thread On Wed, Aug 30, 2023 at 6:25 AM Helen Koike wrote: > > Hi all, > > Thanks for you comments. > > On 30/08/2023 08:37, Maxime Ripard wrote: > > On Wed, Aug 30, 2023 at 01:58:31PM +0300, Jani Nikula wrote: > >> On Wed, 30 Aug 2023, Maxime Ripard wrote: > >>> On Tue, Aug 22, 2023 at 04:26:06PM +0200, Daniel Vetter wrote: > On Fri, Aug 11, 2023 at 02:19:53PM -0300, Helen Koike wrote: > > From: Tomeu Vizoso > > > > Developers can easily execute several tests on different devices > > by just pushing their branch to their fork in a repository hosted > > on gitlab.freedesktop.org which has an infrastructure to run jobs > > in several runners and farms with different devices. > > > > There are also other automated tools that uprev dependencies, > > monitor the infra, and so on that are already used by the Mesa > > project, and we can reuse them too. > > > > Also, store expectations about what the DRM drivers are supposed > > to pass in the IGT test suite. By storing the test expectations > > along with the code, we can make sure both stay in sync with each > > other so we can know when a code change breaks those expectations. > > > > Also, include a configuration file that points to the out-of-tree > > CI scripts. > > > > This will allow all contributors to drm to reuse the infrastructure > > already in gitlab.freedesktop.org to test the driver on several > > generations of the hardware. > > > > Signed-off-by: Tomeu Vizoso > > Signed-off-by: Helen Koike > > Acked-by: Daniel Stone > > Acked-by: Rob Clark > > Tested-by: Rob Clark > > Ok I pushed this into a topic/drm-ci branch in drm.git and asked sfr to > include that branch in linux-next. > > But also I'd like to see a lot more acks here, we should be able to at > least pile up a bunch of (driver) maintainers from drm-misc in support of > this. Also maybe media, at least I've heard noises that they're maybe > interested too? Plus anyone else, the more the better. > >>> > >>> I'm not really convinced by that approach at all, and most of the issues > >>> I see are shown by the follow-up series here: > >> > >> I'm not fully convinced either, more like "let's see". In that narrow > >> sense, ack. I don't see harm in trying, if you're also open to backing > >> off in case it does not pan out. > >> > >>> https://lore.kernel.org/dri-devel/20230825122435.316272-1-vignesh.ra...@collabora.com/ > >>> > >>>* We hardcode a CI farm setup into the kernel We do have farm status out of tree so we don't need to push a kernel patch for outages. Other than that, I can go either way, with the scripts and related yml in tree or out of tree. But the expectation files (ie. the patch you are complaining about) absolutely need to be in-tree. It must be possible to update them in sync with driver changes that fix tests. There may be a bit of related churn initially ie. based on our lengthy experience at this point with mesa CI, we can't know about all the flaky tests until people start using CI in anger ;-) > > > These could be out of tree. > > There is a version outside the kernel tree where you just point the CI > configuration to a url: > https://gitlab.freedesktop.org/gfx-ci/drm-ci/-/merge_requests/1 > > We were discussing it here > https://www.linuxtv.org/cgi-bin/mailman/private/linuxtv-ci/2023-August/27.html > > (I guess Sima's reply didn't got into the mailing list) but the argument > of not having out of tree repo is due to historical bad experience of > having to sync the kernel with the code and it can become messy. > > > >>> > >>>* We cannot trust that the code being run is actually the one being > >>> pushed into gitlab > > > We can improve this if this is a requirement. > For DTS configuration we can work with overlays (which is the current > modification on that patchset). For other changes that are not suitable > to upstream (and should be rare) we can see if we work with the > `-external-fixes` approach or another approach, we can check it case by > case to understand why it is not suitable for upstream. > IMHO the occasional need for extra patches is a fact of life with the kernel development process, and we'll have to live with this until _all_ kernel patches run thru pre-merge CI. (I'm not holding my breath, but who knows..) If some particular board doesn't boot because of some early-rc breakage elsewhere in the kernel, then we can't run CI. > > >>> > >>>* IMO, and I know we disagree here, any IGT test we enable for a given > >>> platform should work, period. Allowing failures and flaky tests just > >>> sweeps whatever issue is there under the rug. If the test is at > >>> fault, we should fix the test, if the driver / kernel is at fault, > >>> then I certainly want to know about it. > > > I believe we need a baseline an
Re: [PATCH v2 08/15] drm/panthor: Add the MMU/VM logical block
On Wed, 30 Aug 2023 15:12:43 +0100 Steven Price wrote: > On 29/08/2023 16:33, Boris Brezillon wrote: > > On Mon, 14 Aug 2023 16:53:09 +0100 > > Steven Price wrote: > > > >>> + > >>> +/** > >>> + * struct panthor_vm_op_ctx - VM operation context > >>> + * > >>> + * With VM operations potentially taking place in a dma-signaling path, > >>> we > >>> + * need to make sure everything that might require resource allocation is > >>> + * pre-allocated upfront. This is what this operation context is far. > >>> + * > >>> + * We also collect resources that have been freed, so we can release them > >>> + * asynchronously, and let the VM_BIND scheduler process the next VM_BIND > >>> + * request. > >>> + */ > >>> +struct panthor_vm_op_ctx { > >>> + /** @rsvd_page_tables: Pages reserved for the MMU page table update. */ > >>> + struct { > >>> + /** @count: Number of pages reserved. */ > >>> + u32 count; > >>> + > >>> + /** @ptr: Point to the first unused page in the @pages table. */ > >>> + u32 ptr; > >>> + > >>> + /** > >>> + * @page: Array of pages that can be used for an MMU page table > >>> update. > >>> + * > >>> + * After an VM operation, there might be free pages left in > >>> this array. > >>> + * They should be returned to the pt_cache as part of the > >>> op_ctx cleanup. > >>> + */ > >>> + void **pages; > >>> + } rsvd_page_tables; > >> > >> Two questions: > >> > >> 1) Would a mempool simplify the implementation? It looks like a > >> reasonable match. > > > > Not sure what you mean by mempool, > > See include/linux/mempool.h Oh, okay. > > > but I'm using a kmem_cache here for > > all page table allocations. The pages that are passed to > > panthor_vm_op_ctx::rsvd_page_tables::pages are allocated from this > > pool. It's just that for each VM operation we pre-allocate page-tables, > > and release those that were not used when the operation is done (we > > over-allocate for the worst case scenario). > > The mempool could, potentially, replace the rsvd_page_tables structure. > The kmem_cache you would still want as that's per-driver. Need to have a closer look at the API to make my mind, but at first glance it seems to be overkill for what I initially had in mind. > > >> > >> 2) Does it really make sense to have a separate pool of memory for every > >> operation? Instead of having a separate pool for each operation, it > >> would be possible to just keep track of the total number needed for all > >> outstanding operations. Then a single (per device or maybe per-VM if > >> necessary) mempool could be resized to ensure it has the right amount of > >> space. > > > > The pool is per-driver (see the global pt_cache). rsvd_page_tables just > > holds pages needed for a specific VM operation. To be more specific, it > > holds pages for the worst case (page table tree is empty, except for the > > root page table). > > What I'm wondering is to we need to keep the pages for each operation in > separate pools. I was not really considering it a pool, more a set of pages that will be used by the VM operation, some of them being returned to the kmem_cache pool if we end up using less (over-provisioning). If we have a mempool, say, at the VM level, that means we have 2 levels of caching: the kmem_cache itself, and the mempool attached to the VM. Is there any benefit here? Do we expect kmem_cache to be too slow for fast/already allocated pages? I do see how over-provisioning can cause us to allocate a lot of pages that end up being unused, but I fail to see how VM/device level caching would solve that, because we still have to dequeue some operations to return pages to the intermediate pool, at which point, we've already lost, because already queued operations reserved the amount of pages they thought they needed for the worst case scenario. Operations being queued after that can pick from the returned pages of course, but that's already the case right now, because we return pages to the kmem_cache as soon as we're done executing a VM operation. The only thing that might help is limiting the number of in-flight VM_BIND jobs per VM (or globally), and then have the submit path return EBUSY or EGAIN so the userspace driver knows it has to retry at a later time. > So instead of having a rsvd_page_tables for each > operation, can we have one global one which is sized appropriately for > all operations that are in flight for the device? The operations are > serialized so there's no contention. Or at least a per-VM pool if we can > operate on multiple VMs at once. We can operate on multiple VMs at once (VM is basically your VkDevice, AKA the logical device), but I'm not too worried about the synchronization that would be incurred by the caching at the panthor_device level. I'm just curious to know what value it would add. I'm also worried that it makes the reservation logic more complex: we need to track wha
Re: [PATCH v11] drm: Add initial ci/ subdirectory
On Wed, Aug 30, 2023 at 10:24:49AM -0300, Helen Koike wrote: > Hi all, > > Thanks for you comments. > > On 30/08/2023 08:37, Maxime Ripard wrote: > > On Wed, Aug 30, 2023 at 01:58:31PM +0300, Jani Nikula wrote: > > > On Wed, 30 Aug 2023, Maxime Ripard wrote: > > > > On Tue, Aug 22, 2023 at 04:26:06PM +0200, Daniel Vetter wrote: > > > > > On Fri, Aug 11, 2023 at 02:19:53PM -0300, Helen Koike wrote: > > > > > > From: Tomeu Vizoso > > > > > > > > > > > > Developers can easily execute several tests on different devices > > > > > > by just pushing their branch to their fork in a repository hosted > > > > > > on gitlab.freedesktop.org which has an infrastructure to run jobs > > > > > > in several runners and farms with different devices. > > > > > > > > > > > > There are also other automated tools that uprev dependencies, > > > > > > monitor the infra, and so on that are already used by the Mesa > > > > > > project, and we can reuse them too. > > > > > > > > > > > > Also, store expectations about what the DRM drivers are supposed > > > > > > to pass in the IGT test suite. By storing the test expectations > > > > > > along with the code, we can make sure both stay in sync with each > > > > > > other so we can know when a code change breaks those expectations. > > > > > > > > > > > > Also, include a configuration file that points to the out-of-tree > > > > > > CI scripts. > > > > > > > > > > > > This will allow all contributors to drm to reuse the infrastructure > > > > > > already in gitlab.freedesktop.org to test the driver on several > > > > > > generations of the hardware. > > > > > > > > > > > > Signed-off-by: Tomeu Vizoso > > > > > > Signed-off-by: Helen Koike > > > > > > Acked-by: Daniel Stone > > > > > > Acked-by: Rob Clark > > > > > > Tested-by: Rob Clark > > > > > > > > > > Ok I pushed this into a topic/drm-ci branch in drm.git and asked sfr > > > > > to > > > > > include that branch in linux-next. > > > > > > > > > > But also I'd like to see a lot more acks here, we should be able to at > > > > > least pile up a bunch of (driver) maintainers from drm-misc in > > > > > support of > > > > > this. Also maybe media, at least I've heard noises that they're maybe > > > > > interested too? Plus anyone else, the more the better. > > > > > > > > I'm not really convinced by that approach at all, and most of the issues > > > > I see are shown by the follow-up series here: > > > > > > I'm not fully convinced either, more like "let's see". In that narrow > > > sense, ack. I don't see harm in trying, if you're also open to backing > > > off in case it does not pan out. > > > > > > > https://lore.kernel.org/dri-devel/20230825122435.316272-1-vignesh.ra...@collabora.com/ > > > > > > > >* We hardcode a CI farm setup into the kernel > > > These could be out of tree. > > There is a version outside the kernel tree where you just point the CI > configuration to a url: > https://gitlab.freedesktop.org/gfx-ci/drm-ci/-/merge_requests/1 > > We were discussing it here > https://www.linuxtv.org/cgi-bin/mailman/private/linuxtv-ci/2023-August/27.html It looks like it's private > (I guess Sima's reply didn't got into the mailing list) but the argument of > not having out of tree repo is due to historical bad experience of having to > sync the kernel with the code and it can become messy. My point is that even though the test strategy might be considered a "property" of the kernel, how you execute it is definitely not and you will have as many setups as you have CI farms. You can't put that into the kernel, just like we don't put the kernel command line in it for example. > > > > > > > >* We cannot trust that the code being run is actually the one being > > > > pushed into gitlab > > > We can improve this if this is a requirement. > For DTS configuration we can work with overlays (which is the current > modification on that patchset). For other changes that are not suitable to > upstream (and should be rare) we can see if we work with the > `-external-fixes` approach or another approach, we can check it case by case > to understand why it is not suitable for upstream. The existence of that branch in itself is an issue to me. Again, it's a matter of trust. How can I trust a branch I barely know about, of which the development is not clear and isn't reviewed by any of the maintainers of the code that might affect the test outcomes. Or put another way, if I run the tests on my machine, it won't work. Why should it work on the CI farm? The branch itself is broken. It might not be due to any of the work I did, but it's broken still. > > > > > > > >* IMO, and I know we disagree here, any IGT test we enable for a > > > > given > > > > platform should work, period. Allowing failures and flaky tests > > > > just > > > > sweeps whatever issue is there under the rug. If the test is at > > > > fault, we should fix the test, if the driver / kernel is at fault, > > > >
Re: [PATCH drm-misc-next 2/3] drm/gpuva_mgr: generalize dma_resv/extobj handling and GEM validation
On Wed, Aug 30, 2023 at 03:42:08PM +0200, Thomas Hellström (Intel) wrote: > > On 8/30/23 14:49, Danilo Krummrich wrote: > > Hi Thomas, > > > > thanks for having a look! > > > > On Wed, Aug 30, 2023 at 09:27:45AM +0200, Thomas Hellström (Intel) wrote: > > > Hi, Danilo. > > > > > > Some quick comments since I'm doing some Xe work in this area. Will > > > probably > > > get back with more. > > > > > > On 8/20/23 23:53, Danilo Krummrich wrote: > > > > So far the DRM GPUVA manager offers common infrastructure to track GPU > > > > VA > > > > allocations and mappings, generically connect GPU VA mappings to their > > > > backing buffers and perform more complex mapping operations on the GPU > > > > VA > > > > space. > > > > > > > > However, there are more design patterns commonly used by drivers, which > > > > can potentially be generalized in order to make the DRM GPUVA manager > > > > represent a basic GPU-VM implementation. In this context, this patch > > > > aims > > > > at generalizing the following elements. > > > > > > > > 1) Provide a common dma-resv for GEM objects not being used outside of > > > > this GPU-VM. > > > > > > > > 2) Provide tracking of external GEM objects (GEM objects which are > > > > shared with other GPU-VMs). > > > > > > > > 3) Provide functions to efficiently lock all GEM objects dma-resv the > > > > GPU-VM contains mappings of. > > > > > > > > 4) Provide tracking of evicted GEM objects the GPU-VM contains mappings > > > > of, such that validation of evicted GEM objects is accelerated. > > > > > > > > 5) Provide some convinience functions for common patterns. > > > > > > > > Rather than being designed as a "framework", the target is to make all > > > > features appear as a collection of optional helper functions, such that > > > > drivers are free to make use of the DRM GPUVA managers basic > > > > functionality and opt-in for other features without setting any feature > > > > flags, just by making use of the corresponding functions. > > > > > > > > Signed-off-by: Danilo Krummrich > > > > --- > > > >drivers/gpu/drm/drm_gpuva_mgr.c | 688 > > > > +++- > > > >include/drm/drm_gem.h | 48 ++- > > > >include/drm/drm_gpuva_mgr.h | 302 +- > > > >3 files changed, 1010 insertions(+), 28 deletions(-) > > > > > > > > diff --git a/drivers/gpu/drm/drm_gpuva_mgr.c > > > > b/drivers/gpu/drm/drm_gpuva_mgr.c > > > > index f86bfad74ff8..69872b205961 100644 > > > > --- a/drivers/gpu/drm/drm_gpuva_mgr.c > > > > +++ b/drivers/gpu/drm/drm_gpuva_mgr.c > > > > @@ -655,6 +655,7 @@ drm_gpuva_range_valid(struct drm_gpuva_manager *mgr, > > > >/** > > > > * drm_gpuva_manager_init() - initialize a &drm_gpuva_manager > > > > * @mgr: pointer to the &drm_gpuva_manager to initialize > > > > + * @drm: the drivers &drm_device > > > > * @name: the name of the GPU VA space > > > > * @start_offset: the start offset of the GPU VA space > > > > * @range: the size of the GPU VA space > > > > @@ -669,6 +670,7 @@ drm_gpuva_range_valid(struct drm_gpuva_manager *mgr, > > > > */ > > > >void > > > >drm_gpuva_manager_init(struct drm_gpuva_manager *mgr, > > > > + struct drm_device *drm, > > > >const char *name, > > > >u64 start_offset, u64 range, > > > >u64 reserve_offset, u64 reserve_range, > > > > @@ -677,6 +679,11 @@ drm_gpuva_manager_init(struct drm_gpuva_manager > > > > *mgr, > > > > mgr->rb.tree = RB_ROOT_CACHED; > > > > INIT_LIST_HEAD(&mgr->rb.list); > > > > + mt_init(&mgr->mt_ext); > > > > + > > > > + INIT_LIST_HEAD(&mgr->evict.list); > > > > + spin_lock_init(&mgr->evict.lock); > > > > + > > > > drm_gpuva_check_overflow(start_offset, range); > > > > mgr->mm_start = start_offset; > > > > mgr->mm_range = range; > > > > @@ -694,6 +701,9 @@ drm_gpuva_manager_init(struct drm_gpuva_manager > > > > *mgr, > > > > reserve_range))) > > > > __drm_gpuva_insert(mgr, > > > > &mgr->kernel_alloc_node); > > > > } > > > > + > > > > + drm_gem_private_object_init(drm, &mgr->d_obj, 0); > > > > + mgr->resv = mgr->d_obj.resv; > > > >} > > > >EXPORT_SYMBOL_GPL(drm_gpuva_manager_init); > > > > @@ -713,10 +723,575 @@ drm_gpuva_manager_destroy(struct > > > > drm_gpuva_manager *mgr) > > > > __drm_gpuva_remove(&mgr->kernel_alloc_node); > > > > WARN(!RB_EMPTY_ROOT(&mgr->rb.tree.rb_root), > > > > -"GPUVA tree is not empty, potentially leaking memory."); > > > > +"GPUVA tree is not empty, potentially leaking memory.\n"); > > > > + > > > > + mtree_destroy(&mgr->mt_ext); > > > > + WARN(!list_empty(&mgr->evict.list), "Evict list should be > > > > empty.\n"); > > > > + > > > > + drm_gem_private_obj
Re: [PATCH v11] drm: Add initial ci/ subdirectory
On 30/08/2023 11:57, Maxime Ripard wrote: On Wed, Aug 30, 2023 at 10:24:49AM -0300, Helen Koike wrote: Hi all, Thanks for you comments. On 30/08/2023 08:37, Maxime Ripard wrote: On Wed, Aug 30, 2023 at 01:58:31PM +0300, Jani Nikula wrote: On Wed, 30 Aug 2023, Maxime Ripard wrote: On Tue, Aug 22, 2023 at 04:26:06PM +0200, Daniel Vetter wrote: On Fri, Aug 11, 2023 at 02:19:53PM -0300, Helen Koike wrote: From: Tomeu Vizoso Developers can easily execute several tests on different devices by just pushing their branch to their fork in a repository hosted on gitlab.freedesktop.org which has an infrastructure to run jobs in several runners and farms with different devices. There are also other automated tools that uprev dependencies, monitor the infra, and so on that are already used by the Mesa project, and we can reuse them too. Also, store expectations about what the DRM drivers are supposed to pass in the IGT test suite. By storing the test expectations along with the code, we can make sure both stay in sync with each other so we can know when a code change breaks those expectations. Also, include a configuration file that points to the out-of-tree CI scripts. This will allow all contributors to drm to reuse the infrastructure already in gitlab.freedesktop.org to test the driver on several generations of the hardware. Signed-off-by: Tomeu Vizoso Signed-off-by: Helen Koike Acked-by: Daniel Stone Acked-by: Rob Clark Tested-by: Rob Clark Ok I pushed this into a topic/drm-ci branch in drm.git and asked sfr to include that branch in linux-next. But also I'd like to see a lot more acks here, we should be able to at least pile up a bunch of (driver) maintainers from drm-misc in support of this. Also maybe media, at least I've heard noises that they're maybe interested too? Plus anyone else, the more the better. I'm not really convinced by that approach at all, and most of the issues I see are shown by the follow-up series here: I'm not fully convinced either, more like "let's see". In that narrow sense, ack. I don't see harm in trying, if you're also open to backing off in case it does not pan out. https://lore.kernel.org/dri-devel/20230825122435.316272-1-vignesh.ra...@collabora.com/ * We hardcode a CI farm setup into the kernel These could be out of tree. There is a version outside the kernel tree where you just point the CI configuration to a url: https://gitlab.freedesktop.org/gfx-ci/drm-ci/-/merge_requests/1 We were discussing it here https://www.linuxtv.org/cgi-bin/mailman/private/linuxtv-ci/2023-August/27.html It looks like it's private (I guess Sima's reply didn't got into the mailing list) but the argument of not having out of tree repo is due to historical bad experience of having to sync the kernel with the code and it can become messy. My point is that even though the test strategy might be considered a "property" of the kernel, how you execute it is definitely not and you will have as many setups as you have CI farms. You can't put that into the kernel, just like we don't put the kernel command line in it for example. > * We cannot trust that the code being run is actually the one being pushed into gitlab We can improve this if this is a requirement. For DTS configuration we can work with overlays (which is the current modification on that patchset). For other changes that are not suitable to upstream (and should be rare) we can see if we work with the `-external-fixes` approach or another approach, we can check it case by case to understand why it is not suitable for upstream. The existence of that branch in itself is an issue to me. Again, it's a matter of trust. How can I trust a branch I barely know about, of which the development is not clear and isn't reviewed by any of the maintainers of the code that might affect the test outcomes. Or put another way, if I run the tests on my machine, it won't work. Why should it work on the CI farm? The branch itself is broken. It might not be due to any of the work I did, but it's broken still. * IMO, and I know we disagree here, any IGT test we enable for a given platform should work, period. Allowing failures and flaky tests just sweeps whatever issue is there under the rug. If the test is at fault, we should fix the test, if the driver / kernel is at fault, then I certainly want to know about it. I believe we need a baseline and understand the current status of tests. If you check the xfails folder in the patch you can see that I had to add a few tests on *-skips.txt since those tests crashes the system and other on *-fails.txt that are consistently not passing. I agree that we need a baseline, but that baseline should be defined by the tests own merits, not their outcome on a particular platform. In other words, I want all drivers to follow that baseline, and if they don't it's a bug we should fix, and we should be vocal about it. We shouldn't ignore
Re: [PATCH v3 0/7] GPU workload hints for better performance
On 8/28/23 17:02, Lazar, Lijo wrote: > [AMD Official Use Only - General] > > > As mentioned with an older version of this series, this is an 'abuse' of > power profile interface. > > This series is oversimplifying what PMFW algorithms are supposed to be doing. > Whatever this series is doing, FW can do it better. > > To explain in simpler terms - it just tries to boost a profile based on ring > type without even knowing how much of activity a job can trigger on a > particular ring. A job scheduled to a GFX ring doesn't deserve a profile > boost unless it can create a certain level of activity. In CPU terms, a job > scheduled to a processor doesn't mean it deserves a frequency boost of that > CPU. At minimum it depends on more details like whether that job is compute > bound or memory bound or memory bound. > > While FW algorithms are designed to do that, this series tries to trivialise > all such things. > > Unless you are able to show the tangible benefits in some terms like > performance, power, or performance per watt, I don't think this should be > the default behaviour where driver tries to override FW just based on job > submissions to rings. I know at least one tangible benefit this would have: a snappier GNOME desktop with lower input → output latency on many laptops. The bootup default profile doesn't work well for that IME. It should also help for issues like https://gitlab.freedesktop.org/drm/amd/-/issues/1500 . That said, I agree this approach is very aggressive. I think it might be acceptable with AC power, not sure about on battery though. (There might be better performance/power profile mechanisms to hook into than AC vs battery) -- Earthling Michel Dänzer| https://redhat.com Libre software enthusiast | Mesa and Xwayland developer
Re: [PATCH v2 09/15] drm/panthor: Add the FW logical block
On 29/08/2023 17:15, Boris Brezillon wrote: > On Wed, 16 Aug 2023 17:01:56 +0100 > Steven Price wrote: > >> On 09/08/2023 17:53, Boris Brezillon wrote: [...] >>> +/** >>> + * panthor_fw_mem_alloc() - Allocate a FW memory object and map it to the >>> MCU VM. >>> + * @ptdev: Device. >>> + * @size: Size of the memory block. >>> + * @bo_flags: BO flags. >>> + * @vm_map_flags: VM_MAP flags. >>> + * @va: Virtual address of the MCU mapping. >>> + * Set to PANTHOR_GEM_ALLOC_VA for automatic VA-assignment. In that case, >>> the >>> + * VA will be allocated in the shared VA space. >>> + * >>> + * Return: A valid pointer in case of success, an ERR_PTR() otherwise. >>> + */ >>> +static struct panthor_fw_mem * >>> +panthor_fw_mem_alloc(struct panthor_device *ptdev, size_t size, >>> +u32 bo_flags, u32 vm_map_flags, u64 va) >>> +{ >>> + struct panthor_fw_mem *mem = kzalloc(sizeof(*mem), GFP_KERNEL); >>> + int ret; >>> + >>> + if (!mem) >>> + return ERR_PTR(-ENOMEM); >>> + >>> + mem->bo = panthor_gem_create_and_map(ptdev, ptdev->fw->vm, >>> +size, bo_flags, vm_map_flags, >>> +&va, NULL); >>> + if (IS_ERR(mem->bo)) { >>> + ret = PTR_ERR(mem->bo); >>> + mem->bo = NULL; >>> + goto err_free_mem; >>> + } >>> + >>> + mem->va = va; >>> + return mem; >>> + >>> +err_free_mem: >>> + panthor_fw_mem_free(ptdev, mem); >>> + return ERR_PTR(ret); >> >> The error handling seems more complex than needed, how about: >> >> struct panthor_fw_mem *mem = kzalloc(sizeof(*mem), GFP_KERNEL); >> struct panthor_gem_object *bo; >> int ret; >> >> if (!mem) >> return ERR_PTR(-ENOMEM); >> >> bo = panthor_gem_create_and_map(ptdev, ptdev->fw->vm, >> size, bo_flags, vm_map_flags, >> &va, NULL); >> >> if (IS_ERR(bo)) { >> kfree(mem); >> return ERR_CAST(bo); >> } >> >> mem->bo = bo; >> mem->va = va; >> return mem; >> >> Which I think also means we don't need the "if (mem->bo)" case in >> panthor_fw_mem_free(). > > Not so sure about that one. I've been adding code to existing functions > and having a structured error path, with free functions that can deal > with partially initialized object makes code addition less error-prone. > I agree on the local bo variable to avoid mem->bo re-initialization > though. Yeah the "free accepting NULL" style is generally a good one, so leaving the NULL check in panthor_fw_mem_free() is fine. It was just in this case having to explicitly assign NULL before the call to panthor_fw_mem_free() looked ugly. >> >>> +} >>> + > > [...] > >>> +/** >>> + * panthor_fw_alloc_suspend_buf_mem() - Allocate a suspend buffer for a >>> command stream group. >>> + * @ptdev: Device. >>> + * @size: Size of the suspend buffer. >>> + * >>> + * Return: A valid pointer in case of success, an ERR_PTR() otherwise. >>> + */ >>> +struct panthor_fw_mem * >>> +panthor_fw_alloc_suspend_buf_mem(struct panthor_device *ptdev, size_t size) >>> +{ >>> + return panthor_fw_mem_alloc(ptdev, size, >>> + DRM_PANTHOR_BO_NO_MMAP, >>> + DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC, >>> + PANTHOR_GEM_ALLOC_VA); >>> +} >>> + >>> +static int panthor_fw_load_section_entry(struct panthor_device *ptdev, >>> +const struct firmware *fw, >>> +struct panthor_fw_binary_iter *iter, >>> +u32 ehdr) >>> +{ >>> + struct panthor_fw_binary_section_entry_hdr hdr; >>> + struct panthor_fw_section *section; >>> + u32 section_size; >>> + u32 name_len; >>> + int ret; >>> + >>> + ret = panthor_fw_binary_iter_read(ptdev, iter, &hdr, sizeof(hdr)); >>> + if (ret) >>> + return ret; >>> + >>> + if (hdr.data.end < hdr.data.start) { >>> + drm_err(&ptdev->base, "Firmware corrupted, data.end < >>> data.start (0x%x < 0x%x)\n", >>> + hdr.data.end, hdr.data.start); >>> + return -EINVAL; >>> + } >>> + >>> + if (hdr.va.end < hdr.va.start) { >>> + drm_err(&ptdev->base, "Firmware corrupted, hdr.va.end < >>> hdr.va.start (0x%x < 0x%x)\n", >>> + hdr.va.end, hdr.va.start); >>> + return -EINVAL; >>> + } >>> + >>> + if (hdr.data.end > fw->size) { >>> + drm_err(&ptdev->base, "Firmware corrupted, file truncated? >>> data_end=0x%x > fw size=0x%zx\n", >>> + hdr.data.end, fw->size); >>> + return -EINVAL; >>> + } >>> + >>> + if ((hdr.va.start & ~PAGE_MASK) != 0 || >>> + (hdr.va.end & ~PAGE_MASK) != 0) { >>> + drm_err(&ptdev->base, "Firmware corrupted, virtual addresses >>> not page aligned: 0x%x-0x%x\n", >>> + hdr.
Re: [PATCH v7 1/1] vfio/nvgpu: Add vfio pci variant module for grace hopper
On Wed, Aug 30, 2023 at 06:50:32AM -0700, Christoph Hellwig wrote: > I know I'm chiming in a bit late, but what ultimate user space is going > to use this? We should not add anything to the kernel that can't > be used without fully open user space. qemu will get the matching VFIO userspace patches, I think they were posted someplace already. > vfio has traditionally been a bit special as it "just" passes devices > through, so any user space could just be a user space driver for a > random device on $FOO bus, including an actual Linux driver in a VM, > but this driver has very specific semantics for a very specific piece > of hardware, so it really needs to be treated like a generic GPU driver > or accelerator driver. This is basically a pre-CXL driver. It takes a PCI device and some non-standard CXL-ish metadata and adapts it to VFIO. In a post-CXL world this same functionality of managing the 'cache coherent BAR' for VFIO would be done generically by some generic vfio-cxl driver. Jason
[PATCH 3/3] drm/gma500: Fix the failure to map the stolen memory
When another discrete video card(SM750 or AST1400) is mounted into the mini PCIe slot of my ASRock AD2550B-ITX board, the gma500 drivers fails to work. It probably because the UEFI firmware of that board forget to initialize the PSB_PGETBL_CTL reg, therefore the value of dev_priv->pge_ctl is 0, then the value of gtt_phys_start is also 0. On normal case, the value of the dev_priv->stolen_base is 0xbf80 for this board, so the value of the vram_stolen_size will be negative in this case, the calculation of the stolen vram size of drm/gma500 is pasted at below: vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base - PAGE_SIZE; = 0 - 0xbf80 - 4096 = 1056764 KiB Which is so large, so this cause the ioremap_wc() fail, see below dmesg for more information. gma500 :00:02.0: enabling device ( -> 0003) gma500 :00:02.0: GPU: power management timed out. gma500 :00:02.0: [drm] Phys start of GTT: 0x0 gma500 :00:02.0: [drm] Stolen memory base 0xbf80, size 1056764KiB x86/PAT: systemd-udevd:386 conflicting memory types bf80-f000 write-combining<->uncached-minus x86/PAT: memtype_reserve failed [mem 0xbf80-0xefff], track write-combining, req write-combining ioremap memtype_reserve failed -16 gma500 :00:02.0: Failure to map stolen base. gma500: probe of :00:02.0 failed with error -12 Regardless, we want this driver works even there have another video card mounted. This patch solve this problem by given 8M stolen memory if the value of pg->gtt_phys_start is zero. And after apply this patch, it works fine. $ dmesg | grep drm gma500 :00:02.0: [drm] Phys start of GTT: 0x0 gma500 :00:02.0: [drm] Stolen memory base 0xbf80, size 8192KiB [drm] Initialized gma500 1.0.0 20140314 for :00:02.0 on minor 0 gma500 :00:02.0: [drm] fb1: gma500drmfb frame buffer device Signed-off-by: Sui Jingfeng --- drivers/gpu/drm/gma500/gem.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c index 6fe78f61e127..0e9971bb24fa 100644 --- a/drivers/gpu/drm/gma500/gem.c +++ b/drivers/gpu/drm/gma500/gem.c @@ -340,7 +340,11 @@ int psb_gem_mm_init(struct drm_device *dev) pg = &dev_priv->gtt; pci_read_config_dword(pdev, PSB_BSM, &dev_priv->stolen_base); - vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base - PAGE_SIZE; + + if (pg->gtt_phys_start) + vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base - PAGE_SIZE; + else + vram_stolen_size = 8 * 1024 * 1024; stolen_size = vram_stolen_size; -- 2.34.1
[PATCH 2/3] drm/gma500: Print the start address of the GTT
The PGTBL_CTL register provides the starting physical memory address of the Graphics Translation Table (GTT). We want to see what's the value in it. This patch is useful for debug. Signed-off-by: Sui Jingfeng --- drivers/gpu/drm/gma500/gtt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c index 379bc218aa6b..112418301866 100644 --- a/drivers/gpu/drm/gma500/gtt.c +++ b/drivers/gpu/drm/gma500/gtt.c @@ -243,6 +243,8 @@ static void psb_gtt_init_ranges(struct drm_psb_private *dev_priv) gtt_mem = &pdev->resource[PSB_GATT_RESOURCE]; } + drm_info(dev, "Phys start of GTT: 0x%llx\n", (u64)gtt_phys_start); + pg->gtt_phys_start = gtt_phys_start; pg->mmu_gatt_start = mmu_gatt_start; pg->gtt_start = gtt_start; -- 2.34.1