From c5bd85353c0e2dac3e30855a9e4953c0c408dfef Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Mon, 2 Dec 2019 15:01:07 +0800 Subject: [PATCH 0001/1537] drm/i915/gvt: remove unused type attributes Only need to get attribute group instead of attributes and it has no use, so remove it. Reviewed-by: Yan Zhao Signed-off-by: Zhenyu Wang Link: http://patchwork.freedesktop.org/patch/msgid/20191202070109.73924-1-zhenyuw@linux.intel.com --- drivers/gpu/drm/i915/gvt/gvt.c | 4 +--- drivers/gpu/drm/i915/gvt/gvt.h | 3 +-- drivers/gpu/drm/i915/gvt/kvmgt.c | 4 +--- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c index 8f37eefa0a02..cb5fa30b8e63 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.c +++ b/drivers/gpu/drm/i915/gvt/gvt.c @@ -120,10 +120,8 @@ static struct attribute_group *gvt_vgpu_type_groups[] = { [0 ... NR_MAX_INTEL_VGPU_TYPES - 1] = NULL, }; -static bool intel_get_gvt_attrs(struct attribute ***type_attrs, - struct attribute_group ***intel_vgpu_type_groups) +static bool intel_get_gvt_attrs(struct attribute_group ***intel_vgpu_type_groups) { - *type_attrs = gvt_type_attrs; *intel_vgpu_type_groups = gvt_vgpu_type_groups; return true; } diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index b47c6acaf9c0..0081b051d3e0 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -570,8 +570,7 @@ struct intel_gvt_ops { void (*vgpu_deactivate)(struct intel_vgpu *); struct intel_vgpu_type *(*gvt_find_vgpu_type)(struct intel_gvt *gvt, const char *name); - bool (*get_gvt_attrs)(struct attribute ***type_attrs, - struct attribute_group ***intel_vgpu_type_groups); + bool (*get_gvt_attrs)(struct attribute_group ***intel_vgpu_type_groups); int (*vgpu_query_plane)(struct intel_vgpu *vgpu, void *); int (*vgpu_get_dmabuf)(struct intel_vgpu *vgpu, unsigned int); int (*write_protect_handler)(struct intel_vgpu *, u64, void *, diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 04a5a0d90823..a699ecade3fc 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -1597,12 +1597,10 @@ static struct mdev_parent_ops intel_vgpu_ops = { static int kvmgt_host_init(struct device *dev, void *gvt, const void *ops) { - struct attribute **kvm_type_attrs; struct attribute_group **kvm_vgpu_type_groups; intel_gvt_ops = ops; - if (!intel_gvt_ops->get_gvt_attrs(&kvm_type_attrs, - &kvm_vgpu_type_groups)) + if (!intel_gvt_ops->get_gvt_attrs(&kvm_vgpu_type_groups)) return -EFAULT; intel_vgpu_ops.supported_type_groups = kvm_vgpu_type_groups; From e5124751892a5ca66d07aead1e74bc6c55638d74 Mon Sep 17 00:00:00 2001 From: Oleg Vasilev Date: Thu, 29 Aug 2019 14:48:48 +0300 Subject: [PATCH 0002/1537] drm: move DP_MAX_DOWNSTREAM_PORTS from i915 to drm core MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DP_MAX_DOWNSTREAM_PORTS=0x10 is a vendor-independent constant. Reviewed-by: Emil Velikov Signed-off-by: Oleg Vasilev Cc: Ville Syrjälä Cc: intel-gfx@lists.freedesktop.org Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20190829114854.1539-1-oleg.vasilev@intel.com --- drivers/gpu/drm/i915/display/intel_display_types.h | 2 -- include/drm/drm_dp_helper.h | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 83ea04149b77..3fd822d536c9 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1178,8 +1178,6 @@ struct intel_hdmi { }; struct intel_dp_mst_encoder; -#define DP_MAX_DOWNSTREAM_PORTS 0x10 - /* * enum link_m_n_set: * When platform provides two set of M_N registers for dp, we can diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 8f8f3632e697..127d6e1d3338 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -392,6 +392,8 @@ # define DP_DS_12BPC 2 # define DP_DS_16BPC 3 +#define DP_MAX_DOWNSTREAM_PORTS 0x10 + /* DP Forward error Correction Registers */ #define DP_FEC_CAPABILITY 0x090 /* 1.4 */ # define DP_FEC_CAPABLE (1 << 0) From b4c32073b8cfb7ad264bf65d40cc7419ff489ea0 Mon Sep 17 00:00:00 2001 From: Oleg Vasilev Date: Thu, 29 Aug 2019 14:48:49 +0300 Subject: [PATCH 0003/1537] drm: always determine branch device with drm_dp_is_branch() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The helper should always be used. Reviewed-by: Emil Velikov Signed-off-by: Oleg Vasilev Cc: Ville Syrjälä Cc: intel-gfx@lists.freedesktop.org Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20190829114854.1539-2-oleg.vasilev@intel.com --- drivers/gpu/drm/drm_dp_helper.c | 3 +-- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 2c7870aef469..f629fc5494a4 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -460,8 +460,7 @@ void drm_dp_downstream_debug(struct seq_file *m, int len; uint8_t rev[2]; int type = port_cap[0] & DP_DS_PORT_TYPE_MASK; - bool branch_device = dpcd[DP_DOWNSTREAMPORT_PRESENT] & - DP_DWN_STRM_PORT_PRESENT; + bool branch_device = drm_dp_is_branch(dpcd); seq_printf(m, "\tDP branch device present: %s\n", branch_device ? "yes" : "no"); diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 2f31d226c6eb..7f6b3e35e396 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -3149,7 +3149,7 @@ static bool downstream_hpd_needs_d0(struct intel_dp *intel_dp) * FIXME should really check all downstream ports... */ return intel_dp->dpcd[DP_DPCD_REV] == 0x11 && - intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT && + drm_dp_is_branch(intel_dp->dpcd) && intel_dp->downstream_ports[0] & DP_DS_PORT_HPD; } From 69654c632d806ac6a37a1d4148de592aae809b40 Mon Sep 17 00:00:00 2001 From: Derek Basehore Date: Sun, 5 Jan 2020 16:51:19 +0100 Subject: [PATCH 0004/1537] drm/connector: Split out orientation quirk detection (v2) Not every platform needs quirk detection for panel orientation, so split the drm_connector_init_panel_orientation_property into two functions. One for platforms without the need for quirks, and the other for platforms that need quirks. Hans de Goede (changes in v2): Rename the function from drm_connector_init_panel_orientation_property to drm_connector_set_panel_orientation[_with_quirk] and pass in the panel-orientation to set. Beside the rename, also make the function set the passed in value only once, if the value was set before (to a value other then DRM_MODE_PANEL_ORIENTATION_UNKNOWN) make any further set calls a no-op. This change is preparation for allowing the user to override the panel-orientation for any connector from the kernel commandline. When the panel-orientation is overridden this way, then we must ignore the panel-orientation detection done by the driver. Reviewed-by: Rodrigo Vivi Signed-off-by: Derek Basehore Signed-off-by: Hans de Goede Acked-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20200105155120.96466-1-hdegoede@redhat.com --- drivers/gpu/drm/drm_connector.c | 76 ++++++++++++++++++------- drivers/gpu/drm/i915/display/icl_dsi.c | 5 +- drivers/gpu/drm/i915/display/intel_dp.c | 9 ++- drivers/gpu/drm/i915/display/vlv_dsi.c | 5 +- include/drm/drm_connector.h | 9 ++- 5 files changed, 72 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 2166000ed057..de5031c4aa49 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1139,7 +1139,8 @@ static const struct drm_prop_enum_list dp_colorspaces[] = { * coordinates, so if userspace rotates the picture to adjust for * the orientation it must also apply the same transformation to the * touchscreen input coordinates. This property is initialized by calling - * drm_connector_init_panel_orientation_property(). + * drm_connector_set_panel_orientation() or + * drm_connector_set_panel_orientation_with_quirk() * * scaling mode: * This property defines how a non-native mode is upscaled to the native @@ -2046,38 +2047,41 @@ void drm_connector_set_vrr_capable_property( EXPORT_SYMBOL(drm_connector_set_vrr_capable_property); /** - * drm_connector_init_panel_orientation_property - - * initialize the connecters panel_orientation property - * @connector: connector for which to init the panel-orientation property. - * @width: width in pixels of the panel, used for panel quirk detection - * @height: height in pixels of the panel, used for panel quirk detection + * drm_connector_set_panel_orientation - sets the connecter's panel_orientation + * @connector: connector for which to set the panel-orientation property. + * @panel_orientation: drm_panel_orientation value to set * - * This function should only be called for built-in panels, after setting - * connector->display_info.panel_orientation first (if known). + * This function sets the connector's panel_orientation and attaches + * a "panel orientation" property to the connector. * - * This function will check for platform specific (e.g. DMI based) quirks - * overriding display_info.panel_orientation first, then if panel_orientation - * is not DRM_MODE_PANEL_ORIENTATION_UNKNOWN it will attach the - * "panel orientation" property to the connector. + * Calling this function on a connector where the panel_orientation has + * already been set is a no-op (e.g. the orientation has been overridden with + * a kernel commandline option). + * + * It is allowed to call this function with a panel_orientation of + * DRM_MODE_PANEL_ORIENTATION_UNKNOWN, in which case it is a no-op. * * Returns: * Zero on success, negative errno on failure. */ -int drm_connector_init_panel_orientation_property( - struct drm_connector *connector, int width, int height) +int drm_connector_set_panel_orientation( + struct drm_connector *connector, + enum drm_panel_orientation panel_orientation) { struct drm_device *dev = connector->dev; struct drm_display_info *info = &connector->display_info; struct drm_property *prop; - int orientation_quirk; - orientation_quirk = drm_get_panel_orientation_quirk(width, height); - if (orientation_quirk != DRM_MODE_PANEL_ORIENTATION_UNKNOWN) - info->panel_orientation = orientation_quirk; - - if (info->panel_orientation == DRM_MODE_PANEL_ORIENTATION_UNKNOWN) + /* Already set? */ + if (info->panel_orientation != DRM_MODE_PANEL_ORIENTATION_UNKNOWN) return 0; + /* Don't attach the property if the orientation is unknown */ + if (panel_orientation == DRM_MODE_PANEL_ORIENTATION_UNKNOWN) + return 0; + + info->panel_orientation = panel_orientation; + prop = dev->mode_config.panel_orientation_property; if (!prop) { prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, @@ -2094,7 +2098,37 @@ int drm_connector_init_panel_orientation_property( info->panel_orientation); return 0; } -EXPORT_SYMBOL(drm_connector_init_panel_orientation_property); +EXPORT_SYMBOL(drm_connector_set_panel_orientation); + +/** + * drm_connector_set_panel_orientation_with_quirk - + * set the connecter's panel_orientation after checking for quirks + * @connector: connector for which to init the panel-orientation property. + * @panel_orientation: drm_panel_orientation value to set + * @width: width in pixels of the panel, used for panel quirk detection + * @height: height in pixels of the panel, used for panel quirk detection + * + * Like drm_connector_set_panel_orientation(), but with a check for platform + * specific (e.g. DMI based) quirks overriding the passed in panel_orientation. + * + * Returns: + * Zero on success, negative errno on failure. + */ +int drm_connector_set_panel_orientation_with_quirk( + struct drm_connector *connector, + enum drm_panel_orientation panel_orientation, + int width, int height) +{ + int orientation_quirk; + + orientation_quirk = drm_get_panel_orientation_quirk(width, height); + if (orientation_quirk != DRM_MODE_PANEL_ORIENTATION_UNKNOWN) + panel_orientation = orientation_quirk; + + return drm_connector_set_panel_orientation(connector, + panel_orientation); +} +EXPORT_SYMBOL(drm_connector_set_panel_orientation_with_quirk); int drm_connector_set_obj_prop(struct drm_mode_object *obj, struct drm_property *property, diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index 006b1a297e6f..4450d98c98a1 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -1667,9 +1667,8 @@ static void icl_dsi_add_properties(struct intel_connector *connector) connector->base.state->scaling_mode = DRM_MODE_SCALE_ASPECT; - connector->base.display_info.panel_orientation = - intel_dsi_get_panel_orientation(connector); - drm_connector_init_panel_orientation_property(&connector->base, + drm_connector_set_panel_orientation_with_quirk(&connector->base, + intel_dsi_get_panel_orientation(connector), connector->panel.fixed_mode->hdisplay, connector->panel.fixed_mode->vdisplay); } diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 7f6b3e35e396..20ccc9422107 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -7401,9 +7401,12 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, intel_connector->panel.backlight.power = intel_edp_backlight_power; intel_panel_setup_backlight(connector, pipe); - if (fixed_mode) - drm_connector_init_panel_orientation_property( - connector, fixed_mode->hdisplay, fixed_mode->vdisplay); + if (fixed_mode) { + /* We do not know the orientation, but their might be a quirk */ + drm_connector_set_panel_orientation_with_quirk(connector, + DRM_MODE_PANEL_ORIENTATION_UNKNOWN, + fixed_mode->hdisplay, fixed_mode->vdisplay); + } return true; diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c index 21e820299107..5b96051f4f7c 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi.c @@ -1638,10 +1638,9 @@ static void vlv_dsi_add_properties(struct intel_connector *connector) connector->base.state->scaling_mode = DRM_MODE_SCALE_ASPECT; - connector->base.display_info.panel_orientation = - vlv_dsi_get_panel_orientation(connector); - drm_connector_init_panel_orientation_property( + drm_connector_set_panel_orientation_with_quirk( &connector->base, + vlv_dsi_get_panel_orientation(connector), connector->panel.fixed_mode->hdisplay, connector->panel.fixed_mode->vdisplay); } diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 221910948b37..2113500b4075 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1552,8 +1552,13 @@ void drm_connector_set_link_status_property(struct drm_connector *connector, uint64_t link_status); void drm_connector_set_vrr_capable_property( struct drm_connector *connector, bool capable); -int drm_connector_init_panel_orientation_property( - struct drm_connector *connector, int width, int height); +int drm_connector_set_panel_orientation( + struct drm_connector *connector, + enum drm_panel_orientation panel_orientation); +int drm_connector_set_panel_orientation_with_quirk( + struct drm_connector *connector, + enum drm_panel_orientation panel_orientation, + int width, int height); int drm_connector_attach_max_bpc_property(struct drm_connector *connector, int min, int max); From 0980939d2a7065e2264022b8b7492a85e7549101 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 5 Jan 2020 16:51:20 +0100 Subject: [PATCH 0005/1537] drm/connector: Hookup the new drm_cmdline_mode panel_orientation member (v2) If the new video=... panel_orientation option is set for a connector, honor it and setup a matching "panel orientation" property on the connector. Changes in v2: -Improve DRM_INFO message to make it clear that the panel_orientation is being forced from the commandline BugLink: https://gitlab.freedesktop.org/plymouth/plymouth/merge_requests/83 Acked-by: Maxime Ripard Signed-off-by: Hans de Goede Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20200105155120.96466-2-hdegoede@redhat.com --- drivers/gpu/drm/drm_connector.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index de5031c4aa49..f632ca05960e 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -140,6 +140,13 @@ static void drm_connector_get_cmdline_mode(struct drm_connector *connector) connector->force = mode->force; } + if (mode->panel_orientation != DRM_MODE_PANEL_ORIENTATION_UNKNOWN) { + DRM_INFO("cmdline forces connector %s panel_orientation to %d\n", + connector->name, mode->panel_orientation); + drm_connector_set_panel_orientation(connector, + mode->panel_orientation); + } + DRM_DEBUG_KMS("cmdline mode for connector %s %s %dx%d@%dHz%s%s%s\n", connector->name, mode->name, mode->xres, mode->yres, From dba9bf0a98c5fcfb3f616bf2446d5aeef67b632c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 8 Jan 2020 14:51:05 +0100 Subject: [PATCH 0006/1537] drm: panel: fix excessive stack usage in td028ttec1_prepare With gcc -O3 in combination with the structleak plug, the compiler can inline very aggressively, leading to rather large stack usage: drivers/gpu/drm/panel/panel-tpo-td028ttec1.c: In function 'td028ttec1_prepare': drivers/gpu/drm/panel/panel-tpo-td028ttec1.c:233:1: error: the frame size of 2768 bytes is larger than 2048 bytes [-Werror=frame-larger-than=] } Marking jbt_reg_write_*() as noinline avoids the case where multiple instances of this function get inlined into the same stack frame and each one adds a copy of 'tx_buf'. The compiler is clearly making some bad decisions here, but I did not open a new bug report as this only happens in combination with the structleak plugin. This fixes mmtom ("init/Kconfig: enable -O3 for all arches") Link: https://lore.kernel.org/lkml/CAK8P3a3jAnFZA3GFRtdYdg1-i-oih3pOQzkkrK-X3BGsFrMiZQ@mail.gmail.com/ Signed-off-by: Arnd Bergmann Signed-off-by: Sam Ravnborg [fix indent] Link: https://patchwork.freedesktop.org/patch/msgid/20200108135116.3687988-1-arnd@arndb.de --- drivers/gpu/drm/panel/panel-tpo-td028ttec1.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-tpo-td028ttec1.c b/drivers/gpu/drm/panel/panel-tpo-td028ttec1.c index cf29405a2dbe..aeca15dfeb3c 100644 --- a/drivers/gpu/drm/panel/panel-tpo-td028ttec1.c +++ b/drivers/gpu/drm/panel/panel-tpo-td028ttec1.c @@ -86,7 +86,12 @@ struct td028ttec1_panel { #define to_td028ttec1_device(p) container_of(p, struct td028ttec1_panel, panel) -static int jbt_ret_write_0(struct td028ttec1_panel *lcd, u8 reg, int *err) +/* + * noinline_for_stack so we don't get multiple copies of tx_buf + * on the stack in case of gcc-plugin-structleak + */ +static int noinline_for_stack +jbt_ret_write_0(struct td028ttec1_panel *lcd, u8 reg, int *err) { struct spi_device *spi = lcd->spi; u16 tx_buf = JBT_COMMAND | reg; @@ -105,8 +110,9 @@ static int jbt_ret_write_0(struct td028ttec1_panel *lcd, u8 reg, int *err) return ret; } -static int jbt_reg_write_1(struct td028ttec1_panel *lcd, - u8 reg, u8 data, int *err) +static int noinline_for_stack +jbt_reg_write_1(struct td028ttec1_panel *lcd, + u8 reg, u8 data, int *err) { struct spi_device *spi = lcd->spi; u16 tx_buf[2]; @@ -128,8 +134,9 @@ static int jbt_reg_write_1(struct td028ttec1_panel *lcd, return ret; } -static int jbt_reg_write_2(struct td028ttec1_panel *lcd, - u8 reg, u16 data, int *err) +static int noinline_for_stack +jbt_reg_write_2(struct td028ttec1_panel *lcd, + u8 reg, u16 data, int *err) { struct spi_device *spi = lcd->spi; u16 tx_buf[3]; From 8d6cb2f7fb90018d9e3efdc9bc95e6da213a352f Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 7 Jan 2020 21:32:19 +0100 Subject: [PATCH 0007/1537] drm/drm_panel: fix export of drm_panel_of_backlight, try #3 Making this IS_REACHABLE() was still wrong, as that just determines whether the lower-level backlight code would be reachable from the panel driver. However, with CONFIG_DRM=y and CONFIG_BACKLIGHT_CLASS_DEVICE=m, the drm_panel_of_backlight is left out of drm_panel.o but the condition tells the driver that it is there, leading to multiple link errors such as ERROR: "drm_panel_of_backlight" [drivers/gpu/drm/panel/panel-sitronix-st7701.ko] undefined! ERROR: "drm_panel_of_backlight" [drivers/gpu/drm/panel/panel-sharp-ls043t1le01.ko] undefined! ERROR: "drm_panel_of_backlight" [drivers/gpu/drm/panel/panel-seiko-43wvf1g.ko] undefined! ERROR: "drm_panel_of_backlight" [drivers/gpu/drm/panel/panel-ronbo-rb070d30.ko] undefined! ERROR: "drm_panel_of_backlight" [drivers/gpu/drm/panel/panel-rocktech-jh057n00900.ko] undefined! ERROR: "drm_panel_of_backlight" [drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.ko] undefined! ERROR: "drm_panel_of_backlight" [drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.ko] undefined! Change the condition to check for whether the function was actually part of the drm module. This version of the patch survived a few hundred randconfig builds, so I have a good feeling this might be the last one for the export. Fixes: 4a34a9dcec94 ("drm/drm_panel: Fix EXPORT of drm_panel_of_backlight() one more time") Fixes: 907aa265fde6 ("drm/drm_panel: fix EXPORT of drm_panel_of_backlight") Fixes: 152dbdeab1b2 ("drm/panel: add backlight support") Signed-off-by: Arnd Bergmann Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200107203231.920256-1-arnd@arndb.de --- include/drm/drm_panel.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h index 121f7aabccd1..6193cb555acc 100644 --- a/include/drm/drm_panel.h +++ b/include/drm/drm_panel.h @@ -198,7 +198,8 @@ static inline struct drm_panel *of_drm_find_panel(const struct device_node *np) } #endif -#if IS_REACHABLE(CONFIG_BACKLIGHT_CLASS_DEVICE) +#if IS_ENABLED(CONFIG_DRM_PANEL) && (IS_BUILTIN(CONFIG_BACKLIGHT_CLASS_DEVICE) || \ + (IS_MODULE(CONFIG_DRM) && IS_MODULE(CONFIG_BACKLIGHT_CLASS_DEVICE))) int drm_panel_of_backlight(struct drm_panel *panel); #else static inline int drm_panel_of_backlight(struct drm_panel *panel) From 53c902b9998aab63c048af5798cbfd33b938cbdd Mon Sep 17 00:00:00 2001 From: Wambui Karuga Date: Thu, 9 Jan 2020 17:20:57 +0300 Subject: [PATCH 0008/1537] drm/rockchip: use DIV_ROUND_UP macro for calculations. Replace the open coded calculation with the more concise and readable DIV_ROUND_UP macro. Signed-off-by: Wambui Karuga Signed-off-by: Heiko Stuebner Link: https://patchwork.freedesktop.org/patch/msgid/20200109142057.10744-1-wambui.karugax@gmail.com --- drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h index 0b3d18c457b2..cc672620d6e0 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h @@ -328,7 +328,7 @@ static inline uint16_t scl_get_bili_dn_vskip(int src_h, int dst_h, { int act_height; - act_height = (src_h + vskiplines - 1) / vskiplines; + act_height = DIV_ROUND_UP(src_h, vskiplines); if (act_height == dst_h) return GET_SCL_FT_BILI_DN(src_h, dst_h) / vskiplines; From 9590a99cfb3bcb472d6e0dd783c2051620c6c096 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 31 Dec 2019 09:12:36 +0100 Subject: [PATCH 0009/1537] drm/rockchip: Add missing vmalloc header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Rockship DRM GEM code uses vmap()/vunmap() so vmalloc header must be included to avoid warnings like (on IA64, compile tested): drivers/gpu/drm/rockchip/rockchip_drm_gem.c: In function ‘rockchip_gem_alloc_iommu’: drivers/gpu/drm/rockchip/rockchip_drm_gem.c:134:20: error: implicit declaration of function ‘vmap’ [-Werror=implicit-function-declaration] Reported-by: kbuild test robot Signed-off-by: Krzysztof Kozlowski Signed-off-by: Heiko Stuebner Link: https://patchwork.freedesktop.org/patch/msgid/1577779956-7612-1-git-send-email-krzk@kernel.org --- drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c index 7582d0e6a60a..0d1884684dcb 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c @@ -6,6 +6,7 @@ #include #include +#include #include #include From 978bd0278f90b5e71a5587ffa9804b43f4996f8c Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Mon, 13 Jan 2020 13:17:39 -0300 Subject: [PATCH 0010/1537] dt-bindings: vendor-prefixes: Add Shenzhen Frida LCD Co., Ltd. Add an entry for Shenzhen Frida LCD Co., Ltd. v2: No change v3: No change Signed-off-by: Paul Cercueil Acked-by: Sam Ravnborg Acked-by: Rob Herring Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200113161741.32061-1-paul@crapouillou.net --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 835579edc971..76069bb51ea4 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -337,6 +337,8 @@ patternProperties: description: Firefly "^focaltech,.*": description: FocalTech Systems Co.,Ltd + "^frida,.*": + description: Shenzhen Frida LCD Co., Ltd. "^friendlyarm,.*": description: Guangzhou FriendlyARM Computer Tech Co., Ltd "^fsl,.*": From 7ab618c9a7e6d3f941b2d71441af218823a81fc2 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Mon, 13 Jan 2020 13:17:40 -0300 Subject: [PATCH 0011/1537] dt-bindings: panel-simple: Add compatible for Frida FRD350H54004 LCD Add bindings documentation for the Frida 3.5" (320x240 pixels) 24-bit TFT LCD panel. v2: Switch documentation from plain text to YAML v3: Simply add new compatible to panel-simple.yaml file instead of adding new file Signed-off-by: Paul Cercueil Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200113161741.32061-2-paul@crapouillou.net --- .../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 8fe60ee2531c..4a8064e31793 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml @@ -37,6 +37,8 @@ properties: - auo,b116xa01 # BOE NV140FHM-N49 14.0" FHD a-Si FT panel - boe,nv140fhmn49 + # Frida FRD350H54004 3.5" QVGA TFT LCD panel + - frida,frd350h54004 # GiantPlus GPM940B0 3.0" QVGA TFT LCD panel - giantplus,gpm940b0 # Satoz SAT050AT40H12R2 5.0" WVGA TFT LCD panel From 7b6bd84336096851225d06f3b176157f305e09a2 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Mon, 13 Jan 2020 13:17:41 -0300 Subject: [PATCH 0012/1537] drm/panel: simple: Add support for the Frida FRD350H54004 panel The FRD350H54004 is a simple 3.5" 320x240 24-bit TFT panel, found for instance inside the Anbernic RG-350 handheld gaming console. v2: Order alphabetically v3: Add connector_type, and update timings according to the constraints listed in the datasheet Signed-off-by: Paul Cercueil Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200113161741.32061-3-paul@crapouillou.net --- drivers/gpu/drm/panel/panel-simple.c | 30 ++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index e14c14ac62b5..d6f77bc494c7 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -1440,6 +1440,33 @@ static const struct panel_desc foxlink_fl500wvr00_a0t = { .bus_format = MEDIA_BUS_FMT_RGB888_1X24, }; +static const struct drm_display_mode frida_frd350h54004_mode = { + .clock = 6000, + .hdisplay = 320, + .hsync_start = 320 + 44, + .hsync_end = 320 + 44 + 16, + .htotal = 320 + 44 + 16 + 20, + .vdisplay = 240, + .vsync_start = 240 + 2, + .vsync_end = 240 + 2 + 6, + .vtotal = 240 + 2 + 6 + 2, + .vrefresh = 60, + .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC, +}; + +static const struct panel_desc frida_frd350h54004 = { + .modes = &frida_frd350h54004_mode, + .num_modes = 1, + .bpc = 8, + .size = { + .width = 77, + .height = 64, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X24, + .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_POSEDGE, + .connector_type = DRM_MODE_CONNECTOR_DPI, +}; + static const struct drm_display_mode friendlyarm_hd702e_mode = { .clock = 67185, .hdisplay = 800, @@ -3309,6 +3336,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "foxlink,fl500wvr00-a0t", .data = &foxlink_fl500wvr00_a0t, + }, { + .compatible = "frida,frd350h54004", + .data = &frida_frd350h54004, }, { .compatible = "friendlyarm,hd702e", .data = &friendlyarm_hd702e, From f4e9894b6952a2819937f363cd42e7cd7894a1e4 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 14 Jan 2020 10:56:47 +0000 Subject: [PATCH 0013/1537] drm/i915/pmu: Correct the rc6 offset upon enabling The rc6 residency starts ticking from 0 from BIOS POST, but the kernel starts measuring the time from its boot. If we start measuruing I915_PMU_RC6_RESIDENCY while the GT is idle, we start our sampling from 0 and then upon first activity (park/unpark) add in all the rc6 residency since boot. After the first park with the sampler engaged, the sleep/active counters are aligned. v2: With a wakeref to be sure Closes: https://gitlab.freedesktop.org/drm/intel/issues/973 Fixes: df6a42053513 ("drm/i915/pmu: Ensure monotonic rc6") Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20200114105648.2172026-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_pmu.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c index 28a82c849bac..ec0299490dd4 100644 --- a/drivers/gpu/drm/i915/i915_pmu.c +++ b/drivers/gpu/drm/i915/i915_pmu.c @@ -637,8 +637,10 @@ static void i915_pmu_enable(struct perf_event *event) container_of(event->pmu, typeof(*i915), pmu.base); unsigned int bit = event_enabled_bit(event); struct i915_pmu *pmu = &i915->pmu; + intel_wakeref_t wakeref; unsigned long flags; + wakeref = intel_runtime_pm_get(&i915->runtime_pm); spin_lock_irqsave(&pmu->lock, flags); /* @@ -648,6 +650,14 @@ static void i915_pmu_enable(struct perf_event *event) BUILD_BUG_ON(ARRAY_SIZE(pmu->enable_count) != I915_PMU_MASK_BITS); GEM_BUG_ON(bit >= ARRAY_SIZE(pmu->enable_count)); GEM_BUG_ON(pmu->enable_count[bit] == ~0); + + if (pmu->enable_count[bit] == 0 && + config_enabled_mask(I915_PMU_RC6_RESIDENCY) & BIT_ULL(bit)) { + pmu->sample[__I915_SAMPLE_RC6_LAST_REPORTED].cur = 0; + pmu->sample[__I915_SAMPLE_RC6].cur = __get_rc6(&i915->gt); + pmu->sleep_last = ktime_get(); + } + pmu->enable |= BIT_ULL(bit); pmu->enable_count[bit]++; @@ -688,6 +698,8 @@ static void i915_pmu_enable(struct perf_event *event) * an existing non-zero value. */ local64_set(&event->hw.prev_count, __i915_pmu_event_read(event)); + + intel_runtime_pm_put(&i915->runtime_pm, wakeref); } static void i915_pmu_disable(struct perf_event *event) From e88e9f8ea4e95df6e76ce6721e93524d3d116705 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 14 Jan 2020 10:56:48 +0000 Subject: [PATCH 0014/1537] drm/i915/gt: Clear rc6 residency trackers across suspend On suspend, the rc6 residency counters (stored in HW registers) will be lost and cleared. However, we keep track of the rc6 residency to provide a continuous 64b sampling, and if we see the HW value go backwards, we assume it overflowed and add on 32b/40b -- an interesting artifact when sampling across suspend. Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20200114105648.2172026-2-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_rc6.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/gt/intel_rc6.c b/drivers/gpu/drm/i915/gt/intel_rc6.c index 9e303c29d6e3..04eeb7740e53 100644 --- a/drivers/gpu/drm/i915/gt/intel_rc6.c +++ b/drivers/gpu/drm/i915/gt/intel_rc6.c @@ -542,6 +542,8 @@ void intel_rc6_init(struct intel_rc6 *rc6) void intel_rc6_sanitize(struct intel_rc6 *rc6) { + memset(rc6->prev_hw_residency, 0, sizeof(rc6->prev_hw_residency)); + if (rc6->enabled) { /* unbalanced suspend/resume */ rpm_get(rc6); rc6->enabled = false; From d8186dd23926bb6457181ced379d1757f594f507 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Sat, 11 Jan 2020 23:11:11 +0000 Subject: [PATCH 0015/1537] drm/i915/guc: Simpler CT message size calculation We need CT message size in bytes so just use that in helper var. Signed-off-by: Michal Wajdeczko Cc: Chris Wilson Cc: Daniele Ceraolo Spurio Reviewed-by: Daniele Ceraolo Spurio Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20200111231114.59208-2-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c index c6f971a049f9..4aa07a53a9cf 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c @@ -627,7 +627,7 @@ static int ct_handle_response(struct intel_guc_ct *ct, const u32 *msg) { u32 header = msg[0]; u32 len = ct_header_get_len(header); - u32 msglen = len + 1; /* total message length including header */ + u32 msgsize = (len + 1) * sizeof(u32); /* msg size in bytes w/header */ u32 fence; u32 status; u32 datalen; @@ -639,7 +639,7 @@ static int ct_handle_response(struct intel_guc_ct *ct, const u32 *msg) /* Response payload shall at least include fence and status */ if (unlikely(len < 2)) { - DRM_ERROR("CT: corrupted response %*ph\n", 4 * msglen, msg); + DRM_ERROR("CT: corrupted response %*ph\n", msgsize, msg); return -EPROTO; } @@ -649,7 +649,7 @@ static int ct_handle_response(struct intel_guc_ct *ct, const u32 *msg) /* Format of the status follows RESPONSE message */ if (unlikely(!INTEL_GUC_MSG_IS_RESPONSE(status))) { - DRM_ERROR("CT: corrupted response %*ph\n", 4 * msglen, msg); + DRM_ERROR("CT: corrupted response %*ph\n", msgsize, msg); return -EPROTO; } @@ -664,7 +664,7 @@ static int ct_handle_response(struct intel_guc_ct *ct, const u32 *msg) } if (unlikely(datalen > req->response_len)) { DRM_ERROR("CT: response %u too long %*ph\n", - req->fence, 4 * msglen, msg); + req->fence, msgsize, msg); datalen = 0; } if (datalen) @@ -677,7 +677,7 @@ static int ct_handle_response(struct intel_guc_ct *ct, const u32 *msg) spin_unlock(&ct->requests.lock); if (!found) - DRM_ERROR("CT: unsolicited response %*ph\n", 4 * msglen, msg); + DRM_ERROR("CT: unsolicited response %*ph\n", msgsize, msg); return 0; } @@ -767,18 +767,18 @@ static int ct_handle_request(struct intel_guc_ct *ct, const u32 *msg) { u32 header = msg[0]; u32 len = ct_header_get_len(header); - u32 msglen = len + 1; /* total message length including header */ + u32 msgsize = (len + 1) * sizeof(u32); /* msg size in bytes w/header */ struct ct_incoming_request *request; unsigned long flags; GEM_BUG_ON(ct_header_is_response(header)); - request = kmalloc(sizeof(*request) + 4 * msglen, GFP_ATOMIC); + request = kmalloc(sizeof(*request) + msgsize, GFP_ATOMIC); if (unlikely(!request)) { - DRM_ERROR("CT: dropping request %*ph\n", 4 * msglen, msg); + DRM_ERROR("CT: dropping request %*ph\n", msgsize, msg); return 0; /* XXX: -ENOMEM ? */ } - memcpy(request->msg, msg, 4 * msglen); + memcpy(request->msg, msg, msgsize); spin_lock_irqsave(&ct->requests.lock, flags); list_add_tail(&request->link, &ct->requests.incoming); From 18c8832523c8509551ee9354225446125aba10d3 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Sat, 11 Jan 2020 23:11:12 +0000 Subject: [PATCH 0016/1537] drm/i915/guc: Introduce CT_ERROR We should start using dev variants of error logging and to simplify that introduce helper macro that will do any necessary conversions to obtain pointer to device struct. Signed-off-by: Michal Wajdeczko Cc: Chris Wilson Cc: Daniele Ceraolo Spurio Reviewed-by: Daniele Ceraolo Spurio Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20200111231114.59208-3-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 46 ++++++++++++++++------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c index 4aa07a53a9cf..eb123543392a 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c @@ -5,7 +5,10 @@ #include "i915_drv.h" #include "intel_guc_ct.h" +#include "gt/intel_gt.h" +#define CT_ERROR(_ct, _fmt, ...) \ + DRM_DEV_ERROR(ct_to_dev(_ct), "CT: " _fmt, ##__VA_ARGS__) #ifdef CONFIG_DRM_I915_DEBUG_GUC #define CT_DEBUG_DRIVER(...) DRM_DEBUG_DRIVER(__VA_ARGS__) #else @@ -48,6 +51,21 @@ static inline struct intel_guc *ct_to_guc(struct intel_guc_ct *ct) return container_of(ct, struct intel_guc, ct); } +static inline struct intel_gt *ct_to_gt(struct intel_guc_ct *ct) +{ + return guc_to_gt(ct_to_guc(ct)); +} + +static inline struct drm_i915_private *ct_to_i915(struct intel_guc_ct *ct) +{ + return ct_to_gt(ct)->i915; +} + +static inline struct device *ct_to_dev(struct intel_guc_ct *ct) +{ + return ct_to_i915(ct)->drm.dev; +} + static inline const char *guc_ct_buffer_type_to_str(u32 type) { switch (type) { @@ -157,8 +175,8 @@ int intel_guc_ct_init(struct intel_guc_ct *ct) */ err = intel_guc_allocate_and_map_vma(guc, PAGE_SIZE, &ct->vma, &blob); - if (err) { - DRM_ERROR("CT: channel allocation failed; err=%d\n", err); + if (unlikely(err)) { + CT_ERROR(ct, "Failed to allocate CT channel (err=%d)\n", err); return err; } @@ -240,7 +258,7 @@ int intel_guc_ct_enable(struct intel_guc_ct *ct) guc_action_deregister_ct_buffer(guc, INTEL_GUC_CT_BUFFER_TYPE_RECV); err_out: - DRM_ERROR("CT: can't open channel; err=%d\n", err); + CT_ERROR(ct, "Failed to open open CT channel (err=%d)\n", err); return err; } @@ -526,8 +544,8 @@ int intel_guc_ct_send(struct intel_guc_ct *ct, const u32 *action, u32 len, ret = ct_send(ct, action, len, response_buf, response_buf_size, &status); if (unlikely(ret < 0)) { - DRM_ERROR("CT: send action %#X failed; err=%d status=%#X\n", - action[0], ret, status); + CT_ERROR(ct, "Sending action %#x failed (err=%d status=%#X)\n", + action[0], ret, status); } else if (unlikely(ret)) { CT_DEBUG_DRIVER("CT: send action %#x returned %d (%#x)\n", action[0], ret, ret); @@ -639,7 +657,7 @@ static int ct_handle_response(struct intel_guc_ct *ct, const u32 *msg) /* Response payload shall at least include fence and status */ if (unlikely(len < 2)) { - DRM_ERROR("CT: corrupted response %*ph\n", msgsize, msg); + CT_ERROR(ct, "Corrupted response %*ph\n", msgsize, msg); return -EPROTO; } @@ -649,7 +667,7 @@ static int ct_handle_response(struct intel_guc_ct *ct, const u32 *msg) /* Format of the status follows RESPONSE message */ if (unlikely(!INTEL_GUC_MSG_IS_RESPONSE(status))) { - DRM_ERROR("CT: corrupted response %*ph\n", msgsize, msg); + CT_ERROR(ct, "Corrupted response %*ph\n", msgsize, msg); return -EPROTO; } @@ -663,8 +681,8 @@ static int ct_handle_response(struct intel_guc_ct *ct, const u32 *msg) continue; } if (unlikely(datalen > req->response_len)) { - DRM_ERROR("CT: response %u too long %*ph\n", - req->fence, msgsize, msg); + CT_ERROR(ct, "Response for %u is too long %*ph\n", + req->fence, msgsize, msg); datalen = 0; } if (datalen) @@ -677,7 +695,7 @@ static int ct_handle_response(struct intel_guc_ct *ct, const u32 *msg) spin_unlock(&ct->requests.lock); if (!found) - DRM_ERROR("CT: unsolicited response %*ph\n", msgsize, msg); + CT_ERROR(ct, "Unsolicited response %*ph\n", msgsize, msg); return 0; } @@ -698,8 +716,8 @@ static void ct_process_request(struct intel_guc_ct *ct, default: fail_unexpected: - DRM_ERROR("CT: unexpected request %x %*ph\n", - action, 4 * len, payload); + CT_ERROR(ct, "Unexpected request %x %*ph\n", + action, 4 * len, payload); break; } } @@ -775,7 +793,7 @@ static int ct_handle_request(struct intel_guc_ct *ct, const u32 *msg) request = kmalloc(sizeof(*request) + msgsize, GFP_ATOMIC); if (unlikely(!request)) { - DRM_ERROR("CT: dropping request %*ph\n", msgsize, msg); + CT_ERROR(ct, "Dropping request %*ph\n", msgsize, msg); return 0; /* XXX: -ENOMEM ? */ } memcpy(request->msg, msg, msgsize); @@ -815,7 +833,7 @@ void intel_guc_ct_event_handler(struct intel_guc_ct *ct) } while (!err); if (GEM_WARN_ON(err == -EPROTO)) { - DRM_ERROR("CT: corrupted message detected!\n"); + CT_ERROR(ct, "Corrupted message: %#x\n", msg[0]); ctb->desc->is_in_error = 1; } } From 59a46ad9f86c235dd38760f7b487169662bff244 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Sat, 11 Jan 2020 23:11:13 +0000 Subject: [PATCH 0017/1537] drm/i915/guc: Update CTB helpers to use CT_ERROR Update GuC CTB action helpers to benefit from new CT_ERROR macro. Signed-off-by: Michal Wajdeczko Cc: Chris Wilson Cc: Daniele Ceraolo Spurio Reviewed-by: Daniele Ceraolo Spurio Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20200111231114.59208-4-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 57 ++++++++++++----------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c index eb123543392a..eb4e56e97f45 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c @@ -107,31 +107,40 @@ static int guc_action_register_ct_buffer(struct intel_guc *guc, sizeof(struct guc_ct_buffer_desc), type }; - int err; /* Can't use generic send(), CT registration must go over MMIO */ - err = intel_guc_send_mmio(guc, action, ARRAY_SIZE(action), NULL, 0); - if (err) - DRM_ERROR("CT: register %s buffer failed; err=%d\n", - guc_ct_buffer_type_to_str(type), err); + return intel_guc_send_mmio(guc, action, ARRAY_SIZE(action), NULL, 0); +} + +static int ct_register_buffer(struct intel_guc_ct *ct, u32 desc_addr, u32 type) +{ + int err = guc_action_register_ct_buffer(ct_to_guc(ct), desc_addr, type); + + if (unlikely(err)) + CT_ERROR(ct, "Failed to register %s buffer (err=%d)\n", + guc_ct_buffer_type_to_str(type), err); return err; } -static int guc_action_deregister_ct_buffer(struct intel_guc *guc, - u32 type) +static int guc_action_deregister_ct_buffer(struct intel_guc *guc, u32 type) { u32 action[] = { INTEL_GUC_ACTION_DEREGISTER_COMMAND_TRANSPORT_BUFFER, CTB_OWNER_HOST, type }; - int err; /* Can't use generic send(), CT deregistration must go over MMIO */ - err = intel_guc_send_mmio(guc, action, ARRAY_SIZE(action), NULL, 0); - if (err) - DRM_ERROR("CT: deregister %s buffer failed; err=%d\n", - guc_ct_buffer_type_to_str(type), err); + return intel_guc_send_mmio(guc, action, ARRAY_SIZE(action), NULL, 0); +} + +static int ct_deregister_buffer(struct intel_guc_ct *ct, u32 type) +{ + int err = guc_action_deregister_ct_buffer(ct_to_guc(ct), type); + + if (unlikely(err)) + CT_ERROR(ct, "Failed to deregister %s buffer (err=%d)\n", + guc_ct_buffer_type_to_str(type), err); return err; } @@ -235,18 +244,17 @@ int intel_guc_ct_enable(struct intel_guc_ct *ct) PAGE_SIZE/4); } - /* register buffers, starting wirh RECV buffer - * descriptors are in first half of the blob + /* + * Register both CT buffers starting with RECV buffer. + * Descriptors are in first half of the blob. */ - err = guc_action_register_ct_buffer(guc, - base + PAGE_SIZE/4 * CTB_RECV, - INTEL_GUC_CT_BUFFER_TYPE_RECV); + err = ct_register_buffer(ct, base + PAGE_SIZE / 4 * CTB_RECV, + INTEL_GUC_CT_BUFFER_TYPE_RECV); if (unlikely(err)) goto err_out; - err = guc_action_register_ct_buffer(guc, - base + PAGE_SIZE/4 * CTB_SEND, - INTEL_GUC_CT_BUFFER_TYPE_SEND); + err = ct_register_buffer(ct, base + PAGE_SIZE / 4 * CTB_SEND, + INTEL_GUC_CT_BUFFER_TYPE_SEND); if (unlikely(err)) goto err_deregister; @@ -255,8 +263,7 @@ int intel_guc_ct_enable(struct intel_guc_ct *ct) return 0; err_deregister: - guc_action_deregister_ct_buffer(guc, - INTEL_GUC_CT_BUFFER_TYPE_RECV); + ct_deregister_buffer(ct, INTEL_GUC_CT_BUFFER_TYPE_RECV); err_out: CT_ERROR(ct, "Failed to open open CT channel (err=%d)\n", err); return err; @@ -275,10 +282,8 @@ void intel_guc_ct_disable(struct intel_guc_ct *ct) ct->enabled = false; if (intel_guc_is_running(guc)) { - guc_action_deregister_ct_buffer(guc, - INTEL_GUC_CT_BUFFER_TYPE_SEND); - guc_action_deregister_ct_buffer(guc, - INTEL_GUC_CT_BUFFER_TYPE_RECV); + ct_deregister_buffer(ct, INTEL_GUC_CT_BUFFER_TYPE_SEND); + ct_deregister_buffer(ct, INTEL_GUC_CT_BUFFER_TYPE_RECV); } } From 88a57514cf79327f13064f83be6186b139bfcc05 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Sat, 11 Jan 2020 23:11:14 +0000 Subject: [PATCH 0018/1537] drm/i915/guc: Use correct name for last CT fence While we have function that returns "next fence" that can be used by new CT request, we internally store value of the last used fence. Signed-off-by: Michal Wajdeczko Cc: Daniele Ceraolo Spurio Cc: Chris Wilson Reviewed-by: Daniele Ceraolo Spurio Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20200111231114.59208-5-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 2 +- drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c index eb4e56e97f45..a55c336cc5ef 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c @@ -290,7 +290,7 @@ void intel_guc_ct_disable(struct intel_guc_ct *ct) static u32 ct_get_next_fence(struct intel_guc_ct *ct) { /* For now it's trivial */ - return ++ct->requests.next_fence; + return ++ct->requests.last_fence; } /** diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h index 3e7fe237cfa5..97913bbb8be3 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h @@ -49,7 +49,7 @@ struct intel_guc_ct { struct intel_guc_ct_buffer ctbs[2]; struct { - u32 next_fence; /* fence to be used with next request to send */ + u32 last_fence; /* last fence used to send request */ spinlock_t lock; /* protects pending requests list */ struct list_head pending; /* requests waiting for response */ From 36c8e356a76e147f0b631fd29838147c01b50d04 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 13 Jan 2020 15:45:55 +0000 Subject: [PATCH 0019/1537] drm/i915/gem: Take local vma references for the parser Take and hold a reference to each of the vma (and their objects) as we process them with the cmdparser. This stops them being freed during the work if the GEM execbuf is interrupted and the request we expected to keep the objects alive is incomplete. Fixes: 686c7c35abc2 ("drm/i915/gem: Asynchronous cmdparser") Closes: https://gitlab.freedesktop.org/drm/intel/issues/970 Signed-off-by: Chris Wilson Cc: Joonas Lahtinen Reviewed-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20200113154555.1909639-1-chris@chris-wilson.co.uk --- .../gpu/drm/i915/gem/i915_gem_execbuffer.c | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index d5a0f5ae4a8b..60c984e10c4a 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -1981,9 +1981,20 @@ static int __eb_parse(struct dma_fence_work *work) pw->trampoline); } +static void __eb_parse_release(struct dma_fence_work *work) +{ + struct eb_parse_work *pw = container_of(work, typeof(*pw), base); + + if (pw->trampoline) + i915_active_release(&pw->trampoline->active); + i915_active_release(&pw->shadow->active); + i915_active_release(&pw->batch->active); +} + static const struct dma_fence_work_ops eb_parse_ops = { .name = "eb_parse", .work = __eb_parse, + .release = __eb_parse_release, }; static int eb_parse_pipeline(struct i915_execbuffer *eb, @@ -1997,6 +2008,20 @@ static int eb_parse_pipeline(struct i915_execbuffer *eb, if (!pw) return -ENOMEM; + err = i915_active_acquire(&eb->batch->active); + if (err) + goto err_free; + + err = i915_active_acquire(&shadow->active); + if (err) + goto err_batch; + + if (trampoline) { + err = i915_active_acquire(&trampoline->active); + if (err) + goto err_shadow; + } + dma_fence_work_init(&pw->base, &eb_parse_ops); pw->engine = eb->engine; @@ -2006,7 +2031,9 @@ static int eb_parse_pipeline(struct i915_execbuffer *eb, pw->shadow = shadow; pw->trampoline = trampoline; - dma_resv_lock(pw->batch->resv, NULL); + err = dma_resv_lock_interruptible(pw->batch->resv, NULL); + if (err) + goto err_trampoline; err = dma_resv_reserve_shared(pw->batch->resv, 1); if (err) @@ -2034,6 +2061,14 @@ static int eb_parse_pipeline(struct i915_execbuffer *eb, err_batch_unlock: dma_resv_unlock(pw->batch->resv); +err_trampoline: + if (trampoline) + i915_active_release(&trampoline->active); +err_shadow: + i915_active_release(&shadow->active); +err_batch: + i915_active_release(&eb->batch->active); +err_free: kfree(pw); return err; } From 103605e0d1e77cfb5d0f5a9e8aba7d97f1b49339 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 10 Jan 2020 20:32:23 +0200 Subject: [PATCH 0020/1537] drm/i915: Make a copy of the ggtt view for slave plane MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_prepare_plane_fb() will always pin plane_state->hw.fb whenever it is present. We copy that from the master plane to the slave plane, but we fail to copy the corresponding ggtt view. Thus when it comes time to pin the slave plane's fb we use some stale ggtt view left over from the last time the plane was used as a non-slave plane. If that previous use involved 90/270 degree rotation or remapping we'll try to shuffle the pages of the new fb around accordingingly. However the new fb may be backed by a bo with less pages than what the ggtt view rotation/remapped info requires, and so we we trip a GEM_BUG(). Steps to reproduce on icl: 1. plane 1: whatever plane 6: largish !NV12 fb + 90 degree rotation 2. plane 1: smallish NV12 fb plane 6: make invisible so it gets slaved to plane 1 3. GEM_BUG() Cc: Chris Wilson Cc: Maarten Lankhorst Closes: https://gitlab.freedesktop.org/drm/intel/issues/951 Fixes: 1f594b209fe1 ("drm/i915: Remove special case slave handling during hw programming, v3.") Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20200110183228.8199-1-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/display/intel_display.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 19ea842cfd84..aa0ece27186c 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -12366,6 +12366,7 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state) /* Copy parameters to slave plane */ linked_state->ctl = plane_state->ctl | PLANE_CTL_YUV420_Y_PLANE; linked_state->color_ctl = plane_state->color_ctl; + linked_state->view = plane_state->view; memcpy(linked_state->color_plane, plane_state->color_plane, sizeof(linked_state->color_plane)); From b63b4feaef7363d2cf46dd76bb6e87e060b2b0de Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 14 Jan 2020 16:00:30 +0000 Subject: [PATCH 0021/1537] drm/i915/selftests: Add a mock i915_vma to the mock_ring Add a i915_vma to the mock_engine/mock_ring so that the core code can always assume the presence of ring->vma. Fixes: 8ccfc20a7d56 ("drm/i915/gt: Mark ring->vma as active while pinned") Signed-off-by: Chris Wilson Reviewed-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20200114160030.2468927-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/mock_engine.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gt/mock_engine.c b/drivers/gpu/drm/i915/gt/mock_engine.c index a560b7eee2cd..f2806381733f 100644 --- a/drivers/gpu/drm/i915/gt/mock_engine.c +++ b/drivers/gpu/drm/i915/gt/mock_engine.c @@ -59,11 +59,26 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine) ring->vaddr = (void *)(ring + 1); atomic_set(&ring->pin_count, 1); + ring->vma = i915_vma_alloc(); + if (!ring->vma) { + kfree(ring); + return NULL; + } + i915_active_init(&ring->vma->active, NULL, NULL); + intel_ring_update_space(ring); return ring; } +static void mock_ring_free(struct intel_ring *ring) +{ + i915_active_fini(&ring->vma->active); + i915_vma_free(ring->vma); + + kfree(ring); +} + static struct i915_request *first_request(struct mock_engine *engine) { return list_first_entry_or_null(&engine->hw_queue, @@ -121,7 +136,7 @@ static void mock_context_destroy(struct kref *ref) GEM_BUG_ON(intel_context_is_pinned(ce)); if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) { - kfree(ce->ring); + mock_ring_free(ce->ring); mock_timeline_unpin(ce->timeline); } From bd3cf6f7ce209a48e55670cc4b95f16fa057a0bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Roberto=20de=20Souza?= Date: Fri, 10 Jan 2020 15:39:02 -0800 Subject: [PATCH 0022/1537] drm/i915/dp/tgl+: Update combo phy vswing tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TGL has now a table for RBR and HBR and another table for HBR2 over combo phys. The HBR2 one has some small changes comparing to the ICL one, so adding two new tables and adding a function to return TGL combo phy tables. v2: - reordered the tgl_combo_phy_ddi_translations_dp_hbr2 to reduce diff (Matt) - removed definition of rates, kept using raw number(Jani and Ville) - changed code to use icl_get_combo_buf_trans() for non-DP as those are equal between TGL and ICL(Matt) BSpec: 49291 Cc: Lucas De Marchi Cc: Matt Roper Cc: Ville Syrjälä Cc: Jani Nikula Signed-off-by: José Roberto de Souza Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20200110233902.154960-1-jose.souza@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 55 ++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 33f1dc3d7c1a..32ea3c7e8b62 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -622,6 +622,34 @@ static const struct tgl_dkl_phy_ddi_buf_trans tgl_dkl_phy_hdmi_ddi_trans[] = { { 0x0, 0x0, 0xA }, /* 10 Full -3 dB */ }; +static const struct cnl_ddi_buf_trans tgl_combo_phy_ddi_translations_dp_hbr[] = { + /* NT mV Trans mV db */ + { 0xA, 0x32, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */ + { 0xA, 0x4F, 0x37, 0x00, 0x08 }, /* 350 500 3.1 */ + { 0xC, 0x71, 0x2F, 0x00, 0x10 }, /* 350 700 6.0 */ + { 0x6, 0x7D, 0x2B, 0x00, 0x14 }, /* 350 900 8.2 */ + { 0xA, 0x4C, 0x3F, 0x00, 0x00 }, /* 500 500 0.0 */ + { 0xC, 0x73, 0x34, 0x00, 0x0B }, /* 500 700 2.9 */ + { 0x6, 0x7F, 0x2F, 0x00, 0x10 }, /* 500 900 5.1 */ + { 0xC, 0x6C, 0x3C, 0x00, 0x03 }, /* 650 700 0.6 */ + { 0x6, 0x7F, 0x35, 0x00, 0x0A }, /* 600 900 3.5 */ + { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 900 900 0.0 */ +}; + +static const struct cnl_ddi_buf_trans tgl_combo_phy_ddi_translations_dp_hbr2[] = { + /* NT mV Trans mV db */ + { 0xA, 0x35, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */ + { 0xA, 0x4F, 0x37, 0x00, 0x08 }, /* 350 500 3.1 */ + { 0xC, 0x63, 0x2F, 0x00, 0x10 }, /* 350 700 6.0 */ + { 0x6, 0x7F, 0x2B, 0x00, 0x14 }, /* 350 900 8.2 */ + { 0xA, 0x47, 0x3F, 0x00, 0x00 }, /* 500 500 0.0 */ + { 0xC, 0x63, 0x34, 0x00, 0x0B }, /* 500 700 2.9 */ + { 0x6, 0x7F, 0x2F, 0x00, 0x10 }, /* 500 900 5.1 */ + { 0xC, 0x61, 0x3C, 0x00, 0x03 }, /* 650 700 0.6 */ + { 0x6, 0x7B, 0x35, 0x00, 0x0A }, /* 600 900 3.5 */ + { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 900 900 0.0 */ +}; + static const struct ddi_buf_trans * bdw_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries) { @@ -901,6 +929,21 @@ icl_get_combo_buf_trans(struct drm_i915_private *dev_priv, int type, int rate, return icl_combo_phy_ddi_translations_dp_hbr2; } +static const struct cnl_ddi_buf_trans * +tgl_get_combo_buf_trans(struct drm_i915_private *dev_priv, int type, int rate, + int *n_entries) +{ + if (type != INTEL_OUTPUT_DP) { + return icl_get_combo_buf_trans(dev_priv, type, rate, n_entries); + } else if (rate > 270000) { + *n_entries = ARRAY_SIZE(tgl_combo_phy_ddi_translations_dp_hbr2); + return tgl_combo_phy_ddi_translations_dp_hbr2; + } + + *n_entries = ARRAY_SIZE(tgl_combo_phy_ddi_translations_dp_hbr); + return tgl_combo_phy_ddi_translations_dp_hbr; +} + static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv, enum port port) { struct ddi_vbt_port_info *port_info = &dev_priv->vbt.ddi_port_info[port]; @@ -909,7 +952,7 @@ static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv, enum port por if (INTEL_GEN(dev_priv) >= 12) { if (intel_phy_is_combo(dev_priv, phy)) - icl_get_combo_buf_trans(dev_priv, INTEL_OUTPUT_HDMI, + tgl_get_combo_buf_trans(dev_priv, INTEL_OUTPUT_HDMI, 0, &n_entries); else n_entries = ARRAY_SIZE(tgl_dkl_phy_hdmi_ddi_trans); @@ -2372,7 +2415,7 @@ u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder) if (INTEL_GEN(dev_priv) >= 12) { if (intel_phy_is_combo(dev_priv, phy)) - icl_get_combo_buf_trans(dev_priv, encoder->type, + tgl_get_combo_buf_trans(dev_priv, encoder->type, intel_dp->link_rate, &n_entries); else n_entries = ARRAY_SIZE(tgl_dkl_phy_dp_ddi_trans); @@ -2567,8 +2610,12 @@ static void icl_ddi_combo_vswing_program(struct drm_i915_private *dev_priv, u32 n_entries, val; int ln; - ddi_translations = icl_get_combo_buf_trans(dev_priv, type, rate, - &n_entries); + if (INTEL_GEN(dev_priv) >= 12) + ddi_translations = tgl_get_combo_buf_trans(dev_priv, type, rate, + &n_entries); + else + ddi_translations = icl_get_combo_buf_trans(dev_priv, type, rate, + &n_entries); if (!ddi_translations) return; From 4ec5abe960ca08aca02897b67682a39321d0a432 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Roberto=20de=20Souza?= Date: Fri, 10 Jan 2020 15:50:45 -0800 Subject: [PATCH 0023/1537] drm/i915/vbt: Rename BDB_LVDS_POWER to BDB_LFP_POWER MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Renaming to match the BSpec and struct name. BSpec: 20150 Cc: Jani Nikula Signed-off-by: José Roberto de Souza Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20200110235045.176640-1-jose.souza@intel.com --- drivers/gpu/drm/i915/display/intel_bios.c | 2 +- drivers/gpu/drm/i915/display/intel_vbt_defs.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index 8beac06e3f10..9a891ef72118 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -686,7 +686,7 @@ parse_power_conservation_features(struct drm_i915_private *dev_priv, if (bdb->version < 228) return; - power = find_section(bdb, BDB_LVDS_POWER); + power = find_section(bdb, BDB_LFP_POWER); if (!power) return; diff --git a/drivers/gpu/drm/i915/display/intel_vbt_defs.h b/drivers/gpu/drm/i915/display/intel_vbt_defs.h index 4d0c23b29248..05c7cbe32eb4 100644 --- a/drivers/gpu/drm/i915/display/intel_vbt_defs.h +++ b/drivers/gpu/drm/i915/display/intel_vbt_defs.h @@ -111,7 +111,7 @@ enum bdb_block_id { BDB_LVDS_LFP_DATA_PTRS = 41, BDB_LVDS_LFP_DATA = 42, BDB_LVDS_BACKLIGHT = 43, - BDB_LVDS_POWER = 44, + BDB_LFP_POWER = 44, BDB_MIPI_CONFIG = 52, BDB_MIPI_SEQUENCE = 53, BDB_COMPRESSION_PARAMETERS = 56, From 455e00f1412fe51fa7bd21ad6fe0015b163fa9e5 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Mon, 16 Dec 2019 19:46:43 -0800 Subject: [PATCH 0024/1537] drm: Add getfb2 ioctl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit getfb2 allows us to pass multiple planes and modifiers, just like addfb2 over addfb. Changes since v2: - add privilege checks from getfb1 since handles should only be returned to master/root Changes since v1: - unused modifiers set to 0 instead of DRM_FORMAT_MOD_INVALID - update ioctl number Signed-off-by: Daniel Stone Signed-off-by: Juston Li Acked-by: Daniel Vetter Reviewed-by: Ville Syrjälä Signed-off-by: Lyude Paul Link: https://patchwork.freedesktop.org/patch/msgid/20191217034642.3814-1-juston.li@intel.com --- drivers/gpu/drm/drm_crtc_internal.h | 2 + drivers/gpu/drm/drm_framebuffer.c | 122 ++++++++++++++++++++++++++++ drivers/gpu/drm/drm_ioctl.c | 1 + include/uapi/drm/drm.h | 2 + 4 files changed, 127 insertions(+) diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index c7d5e4c21423..16f2413403aa 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h @@ -216,6 +216,8 @@ int drm_mode_rmfb_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int drm_mode_getfb(struct drm_device *dev, void *data, struct drm_file *file_priv); +int drm_mode_getfb2_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); int drm_mode_dirtyfb_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index 57564318ceea..57ac94ce9b9e 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -548,7 +549,128 @@ int drm_mode_getfb(struct drm_device *dev, out: drm_framebuffer_put(fb); + return ret; +} +/** + * drm_mode_getfb2 - get extended FB info + * @dev: drm device for the ioctl + * @data: data pointer for the ioctl + * @file_priv: drm file for the ioctl call + * + * Lookup the FB given its ID and return info about it. + * + * Called by the user via ioctl. + * + * Returns: + * Zero on success, negative errno on failure. + */ +int drm_mode_getfb2_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv) +{ + struct drm_mode_fb_cmd2 *r = data; + struct drm_framebuffer *fb; + unsigned int i; + int ret; + + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return -EINVAL; + + fb = drm_framebuffer_lookup(dev, file_priv, r->fb_id); + if (!fb) + return -ENOENT; + + /* For multi-plane framebuffers, we require the driver to place the + * GEM objects directly in the drm_framebuffer. For single-plane + * framebuffers, we can fall back to create_handle. + */ + if (!fb->obj[0] && + (fb->format->num_planes > 1 || !fb->funcs->create_handle)) { + ret = -ENODEV; + goto out; + } + + r->height = fb->height; + r->width = fb->width; + r->pixel_format = fb->format->format; + + r->flags = 0; + if (dev->mode_config.allow_fb_modifiers) + r->flags |= DRM_MODE_FB_MODIFIERS; + + for (i = 0; i < ARRAY_SIZE(r->handles); i++) { + r->handles[i] = 0; + r->pitches[i] = 0; + r->offsets[i] = 0; + r->modifier[i] = 0; + } + + for (i = 0; i < fb->format->num_planes; i++) { + r->pitches[i] = fb->pitches[i]; + r->offsets[i] = fb->offsets[i]; + if (dev->mode_config.allow_fb_modifiers) + r->modifier[i] = fb->modifier; + } + + /* GET_FB2() is an unprivileged ioctl so we must not return a + * buffer-handle to non master/root processes! To match GET_FB() + * just return invalid handles (0) for non masters/root + * rather than making GET_FB2() privileged. + */ + if (!drm_is_current_master(file_priv) && !capable(CAP_SYS_ADMIN)) { + ret = 0; + goto out; + } + + for (i = 0; i < fb->format->num_planes; i++) { + int j; + + /* If we reuse the same object for multiple planes, also + * return the same handle. + */ + for (j = 0; j < i; j++) { + if (fb->obj[i] == fb->obj[j]) { + r->handles[i] = r->handles[j]; + break; + } + } + + if (r->handles[i]) + continue; + + if (fb->obj[i]) { + ret = drm_gem_handle_create(file_priv, fb->obj[i], + &r->handles[i]); + } else { + WARN_ON(i > 0); + ret = fb->funcs->create_handle(fb, file_priv, + &r->handles[i]); + } + + if (ret != 0) + goto out; + } + +out: + if (ret != 0) { + /* Delete any previously-created handles on failure. */ + for (i = 0; i < ARRAY_SIZE(r->handles); i++) { + int j; + + if (r->handles[i]) + drm_gem_handle_delete(file_priv, r->handles[i]); + + /* Zero out any handles identical to the one we just + * deleted. + */ + for (j = i + 1; j < ARRAY_SIZE(r->handles); j++) { + if (r->handles[j] == r->handles[i]) + r->handles[j] = 0; + } + } + } + + drm_framebuffer_put(fb); return ret; } diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 5afb39688b55..9e41972c4bbc 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -671,6 +671,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_connector_property_set_ioctl, DRM_MASTER), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, 0), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, 0), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB2, drm_mode_getfb2_ioctl, 0), DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb_ioctl, 0), DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2_ioctl, 0), DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb_ioctl, 0), diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index 868bf7996c0f..808b48a93330 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -948,6 +948,8 @@ extern "C" { #define DRM_IOCTL_SYNCOBJ_TRANSFER DRM_IOWR(0xCC, struct drm_syncobj_transfer) #define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL DRM_IOWR(0xCD, struct drm_syncobj_timeline_array) +#define DRM_IOCTL_MODE_GETFB2 DRM_IOWR(0xCE, struct drm_mode_fb_cmd2) + /** * Device specific ioctls should only be in their respective headers * The device specific ioctl range is from 0x40 to 0x9f. From f22fd334890e0e24305aaa7249ff56baba082eca Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Fri, 10 Jan 2020 17:45:11 -0800 Subject: [PATCH 0025/1537] drm/i915/gen11: Add additional pcode status values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I don't think we've ever hit these new error codes, but they're documented in the gen11 pcode document, so we might as well add them to the handler. Signed-off-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20200111014511.2988923-1-matthew.d.roper@intel.com Reviewed-by: José Roberto de Souza --- drivers/gpu/drm/i915/i915_reg.h | 2 ++ drivers/gpu/drm/i915/intel_sideband.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 6cc55c103f67..e5071af4a3b3 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -8987,6 +8987,8 @@ enum { #define GEN6_PCODE_UNIMPLEMENTED_CMD 0xFF #define GEN7_PCODE_TIMEOUT 0x2 #define GEN7_PCODE_ILLEGAL_DATA 0x3 +#define GEN11_PCODE_ILLEGAL_SUBCOMMAND 0x4 +#define GEN11_PCODE_LOCKED 0x6 #define GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE 0x10 #define GEN6_PCODE_WRITE_RC6VIDS 0x4 #define GEN6_PCODE_READ_RC6VIDS 0x5 diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c index cbfb7171d62d..3361fdc41ee1 100644 --- a/drivers/gpu/drm/i915/intel_sideband.c +++ b/drivers/gpu/drm/i915/intel_sideband.c @@ -365,6 +365,10 @@ static inline int gen7_check_mailbox_status(u32 mbox) return -ETIMEDOUT; case GEN7_PCODE_ILLEGAL_DATA: return -EINVAL; + case GEN11_PCODE_ILLEGAL_SUBCOMMAND: + return -ENXIO; + case GEN11_PCODE_LOCKED: + return -EBUSY; case GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE: return -EOVERFLOW; default: From c43c5a8818d4c399e38f636495fb02a8ff8a029a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 5 Dec 2019 17:43:40 +0200 Subject: [PATCH 0026/1537] drm/i915/params: add i915 parameters to debugfs Add a debugfs subdirectory i915_params with all the i915 module parameters. This is a first step, with lots of boilerplate, and not much benefit yet. This will result in a new device specific debugfs directory at /sys/kernel/debug/dri//i915_params duplicating the module specific sysfs directory at /sys/module/i915/parameters/. Going forward, all users of the parameters should use the debugfs, with the module parameters being phased out. Add debugfs permissions to I915_PARAMS_FOR_EACH(). This duplicates the mode with module parameter sysfs, but the goal is to make the module parameters read-only initial values for device specific parameters. 0 mode will bypass debugfs creation. Use it for verbose_state_checks which will need special attention in follow-up work. Reviewed-by: Chris Wilson Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/600101c8433e7caf9303663fc85a9972fa1f05e7.1575560168.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile | 5 +- drivers/gpu/drm/i915/i915_debugfs.c | 4 +- drivers/gpu/drm/i915/i915_debugfs_params.c | 233 +++++++++++++++++++++ drivers/gpu/drm/i915/i915_debugfs_params.h | 14 ++ drivers/gpu/drm/i915/i915_params.c | 2 +- drivers/gpu/drm/i915/i915_params.h | 76 +++---- 6 files changed, 294 insertions(+), 40 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_debugfs_params.c create mode 100644 drivers/gpu/drm/i915/i915_debugfs_params.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index b8c5f8934dbd..3c88d7d8c764 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -66,7 +66,10 @@ i915-y += \ i915_user_extensions.o i915-$(CONFIG_COMPAT) += i915_ioc32.o -i915-$(CONFIG_DEBUG_FS) += i915_debugfs.o display/intel_pipe_crc.o +i915-$(CONFIG_DEBUG_FS) += \ + i915_debugfs.o \ + i915_debugfs_params.o \ + display/intel_pipe_crc.o i915-$(CONFIG_PERF_EVENTS) += i915_pmu.o # "Graphics Technology" (aka we talk to the gpu) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index d5a9b8a964c2..c05fa4205de8 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -48,6 +48,7 @@ #include "gt/uc/intel_guc_submission.h" #include "i915_debugfs.h" +#include "i915_debugfs_params.h" #include "i915_irq.h" #include "i915_trace.h" #include "intel_csr.h" @@ -4311,9 +4312,10 @@ int i915_debugfs_register(struct drm_i915_private *dev_priv) struct drm_minor *minor = dev_priv->drm.primary; int i; + i915_debugfs_params(dev_priv); + debugfs_create_file("i915_forcewake_user", S_IRUSR, minor->debugfs_root, to_i915(minor->dev), &i915_forcewake_fops); - for (i = 0; i < ARRAY_SIZE(i915_debugfs_files); i++) { debugfs_create_file(i915_debugfs_files[i].name, S_IRUGO | S_IWUSR, diff --git a/drivers/gpu/drm/i915/i915_debugfs_params.c b/drivers/gpu/drm/i915/i915_debugfs_params.c new file mode 100644 index 000000000000..7f1af5a35ca1 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_debugfs_params.c @@ -0,0 +1,233 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2019 Intel Corporation + */ + +#include + +#include "i915_drv.h" +#include "i915_params.h" + +/* int param */ +static int i915_param_int_show(struct seq_file *m, void *data) +{ + int *value = m->private; + + seq_printf(m, "%d\n", *value); + + return 0; +} + +static int i915_param_int_open(struct inode *inode, struct file *file) +{ + return single_open(file, i915_param_int_show, inode->i_private); +} + +static ssize_t i915_param_int_write(struct file *file, + const char __user *ubuf, size_t len, + loff_t *offp) +{ + struct seq_file *m = file->private_data; + int *value = m->private; + int ret; + + ret = kstrtoint_from_user(ubuf, len, 0, value); + + return ret ?: len; +} + +static const struct file_operations i915_param_int_fops = { + .owner = THIS_MODULE, + .open = i915_param_int_open, + .read = seq_read, + .write = i915_param_int_write, + .llseek = default_llseek, + .release = single_release, +}; + +static const struct file_operations i915_param_int_fops_ro = { + .owner = THIS_MODULE, + .open = i915_param_int_open, + .read = seq_read, + .llseek = default_llseek, + .release = single_release, +}; + +/* unsigned int param */ +static int i915_param_uint_show(struct seq_file *m, void *data) +{ + unsigned int *value = m->private; + + seq_printf(m, "%u\n", *value); + + return 0; +} + +static int i915_param_uint_open(struct inode *inode, struct file *file) +{ + return single_open(file, i915_param_uint_show, inode->i_private); +} + +static ssize_t i915_param_uint_write(struct file *file, + const char __user *ubuf, size_t len, + loff_t *offp) +{ + struct seq_file *m = file->private_data; + unsigned int *value = m->private; + int ret; + + ret = kstrtouint_from_user(ubuf, len, 0, value); + + return ret ?: len; +} + +static const struct file_operations i915_param_uint_fops = { + .owner = THIS_MODULE, + .open = i915_param_uint_open, + .read = seq_read, + .write = i915_param_uint_write, + .llseek = default_llseek, + .release = single_release, +}; + +static const struct file_operations i915_param_uint_fops_ro = { + .owner = THIS_MODULE, + .open = i915_param_uint_open, + .read = seq_read, + .llseek = default_llseek, + .release = single_release, +}; + +/* char * param */ +static int i915_param_charp_show(struct seq_file *m, void *data) +{ + const char **s = m->private; + + seq_printf(m, "%s\n", *s); + + return 0; +} + +static int i915_param_charp_open(struct inode *inode, struct file *file) +{ + return single_open(file, i915_param_charp_show, inode->i_private); +} + +static ssize_t i915_param_charp_write(struct file *file, + const char __user *ubuf, size_t len, + loff_t *offp) +{ + struct seq_file *m = file->private_data; + char **s = m->private; + char *new, *old; + + /* FIXME: remove locking after params aren't the module params */ + kernel_param_lock(THIS_MODULE); + + old = *s; + new = strndup_user(ubuf, PAGE_SIZE); + if (IS_ERR(new)) { + len = PTR_ERR(new); + goto out; + } + + *s = new; + + kfree(old); +out: + kernel_param_unlock(THIS_MODULE); + + return len; +} + +static const struct file_operations i915_param_charp_fops = { + .owner = THIS_MODULE, + .open = i915_param_charp_open, + .read = seq_read, + .write = i915_param_charp_write, + .llseek = default_llseek, + .release = single_release, +}; + +static const struct file_operations i915_param_charp_fops_ro = { + .owner = THIS_MODULE, + .open = i915_param_charp_open, + .read = seq_read, + .llseek = default_llseek, + .release = single_release, +}; + +#define RO(mode) (((mode) & 0222) == 0) + +static struct dentry * +i915_debugfs_create_int(const char *name, umode_t mode, + struct dentry *parent, int *value) +{ + return debugfs_create_file_unsafe(name, mode, parent, value, + RO(mode) ? &i915_param_int_fops_ro : + &i915_param_int_fops); +} + +static struct dentry * +i915_debugfs_create_uint(const char *name, umode_t mode, + struct dentry *parent, unsigned int *value) +{ + return debugfs_create_file_unsafe(name, mode, parent, value, + RO(mode) ? &i915_param_uint_fops_ro : + &i915_param_uint_fops); +} + +static struct dentry * +i915_debugfs_create_charp(const char *name, umode_t mode, + struct dentry *parent, char **value) +{ + return debugfs_create_file(name, mode, parent, value, + RO(mode) ? &i915_param_charp_fops_ro : + &i915_param_charp_fops); +} + +static __always_inline void +_i915_param_create_file(struct dentry *parent, const char *name, + const char *type, int mode, void *value) +{ + if (!mode) + return; + + if (!__builtin_strcmp(type, "bool")) + debugfs_create_bool(name, mode, parent, value); + else if (!__builtin_strcmp(type, "int")) + i915_debugfs_create_int(name, mode, parent, value); + else if (!__builtin_strcmp(type, "unsigned int")) + i915_debugfs_create_uint(name, mode, parent, value); + else if (!__builtin_strcmp(type, "unsigned long")) + debugfs_create_ulong(name, mode, parent, value); + else if (!__builtin_strcmp(type, "char *")) + i915_debugfs_create_charp(name, mode, parent, value); + else + WARN(1, "no debugfs fops defined for param type %s (i915.%s)\n", + type, name); +} + +/* add a subdirectory with files for each i915 param */ +struct dentry *i915_debugfs_params(struct drm_i915_private *i915) +{ + struct drm_minor *minor = i915->drm.primary; + struct i915_params *params = &i915_modparams; + struct dentry *dir; + + dir = debugfs_create_dir("i915_params", minor->debugfs_root); + if (IS_ERR(dir)) + return dir; + + /* + * Note: We could create files for params needing special handling + * here. Set mode in params to 0 to skip the generic create file, or + * just let the generic create file fail silently with -EEXIST. + */ + +#define REGISTER(T, x, unused, mode, ...) _i915_param_create_file(dir, #x, #T, mode, ¶ms->x); + I915_PARAMS_FOR_EACH(REGISTER); +#undef REGISTER + + return dir; +} diff --git a/drivers/gpu/drm/i915/i915_debugfs_params.h b/drivers/gpu/drm/i915/i915_debugfs_params.h new file mode 100644 index 000000000000..66567076546b --- /dev/null +++ b/drivers/gpu/drm/i915/i915_debugfs_params.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __I915_DEBUGFS_PARAMS__ +#define __I915_DEBUGFS_PARAMS__ + +struct dentry; +struct drm_i915_private; + +struct dentry *i915_debugfs_params(struct drm_i915_private *i915); + +#endif /* __I915_DEBUGFS_PARAMS__ */ diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 1dd1f3652795..64009e99073d 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -35,7 +35,7 @@ MODULE_PARM_DESC(name, desc) struct i915_params i915_modparams __read_mostly = { -#define MEMBER(T, member, value) .member = (value), +#define MEMBER(T, member, value, ...) .member = (value), I915_PARAMS_FOR_EACH(MEMBER) #undef MEMBER }; diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index 31b88f297fbc..be6089e4f9e6 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -36,49 +36,51 @@ struct drm_printer; /* * Invoke param, a function-like macro, for each i915 param, with arguments: * - * param(type, name, value) + * param(type, name, value, mode) * - * type: parameter type, one of {bool, int, unsigned int, char *} + * type: parameter type, one of {bool, int, unsigned int, unsigned long, char *} * name: name of the parameter * value: initial/default value of the parameter + * mode: debugfs file permissions, one of {0400, 0600, 0}, use 0 to not create + * debugfs file */ #define I915_PARAMS_FOR_EACH(param) \ - param(char *, vbt_firmware, NULL) \ - param(int, modeset, -1) \ - param(int, lvds_channel_mode, 0) \ - param(int, panel_use_ssc, -1) \ - param(int, vbt_sdvo_panel_type, -1) \ - param(int, enable_dc, -1) \ - param(int, enable_fbc, -1) \ - param(int, enable_psr, -1) \ - param(int, disable_power_well, -1) \ - param(int, enable_ips, 1) \ - param(int, invert_brightness, 0) \ - param(int, enable_guc, 0) \ - param(int, guc_log_level, -1) \ - param(char *, guc_firmware_path, NULL) \ - param(char *, huc_firmware_path, NULL) \ - param(char *, dmc_firmware_path, NULL) \ - param(int, mmio_debug, -IS_ENABLED(CONFIG_DRM_I915_DEBUG_MMIO)) \ - param(int, edp_vswing, 0) \ - param(int, reset, 3) \ - param(unsigned int, inject_probe_failure, 0) \ - param(int, fastboot, -1) \ - param(int, enable_dpcd_backlight, 0) \ - param(char *, force_probe, CONFIG_DRM_I915_FORCE_PROBE) \ - param(unsigned long, fake_lmem_start, 0) \ + param(char *, vbt_firmware, NULL, 0400) \ + param(int, modeset, -1, 0400) \ + param(int, lvds_channel_mode, 0, 0400) \ + param(int, panel_use_ssc, -1, 0600) \ + param(int, vbt_sdvo_panel_type, -1, 0400) \ + param(int, enable_dc, -1, 0400) \ + param(int, enable_fbc, -1, 0600) \ + param(int, enable_psr, -1, 0600) \ + param(int, disable_power_well, -1, 0400) \ + param(int, enable_ips, 1, 0600) \ + param(int, invert_brightness, 0, 0600) \ + param(int, enable_guc, 0, 0400) \ + param(int, guc_log_level, -1, 0400) \ + param(char *, guc_firmware_path, NULL, 0400) \ + param(char *, huc_firmware_path, NULL, 0400) \ + param(char *, dmc_firmware_path, NULL, 0400) \ + param(int, mmio_debug, -IS_ENABLED(CONFIG_DRM_I915_DEBUG_MMIO), 0600) \ + param(int, edp_vswing, 0, 0400) \ + param(int, reset, 3, 0600) \ + param(unsigned int, inject_probe_failure, 0, 0600) \ + param(int, fastboot, -1, 0600) \ + param(int, enable_dpcd_backlight, 0, 0600) \ + param(char *, force_probe, CONFIG_DRM_I915_FORCE_PROBE, 0400) \ + param(unsigned long, fake_lmem_start, 0, 0400) \ /* leave bools at the end to not create holes */ \ - param(bool, alpha_support, IS_ENABLED(CONFIG_DRM_I915_ALPHA_SUPPORT)) \ - param(bool, enable_hangcheck, true) \ - param(bool, prefault_disable, false) \ - param(bool, load_detect_test, false) \ - param(bool, force_reset_modeset_test, false) \ - param(bool, error_capture, true) \ - param(bool, disable_display, false) \ - param(bool, verbose_state_checks, true) \ - param(bool, nuclear_pageflip, false) \ - param(bool, enable_dp_mst, true) \ - param(bool, enable_gvt, false) + param(bool, alpha_support, IS_ENABLED(CONFIG_DRM_I915_ALPHA_SUPPORT), 0400) \ + param(bool, enable_hangcheck, true, 0600) \ + param(bool, prefault_disable, false, 0600) \ + param(bool, load_detect_test, false, 0600) \ + param(bool, force_reset_modeset_test, false, 0600) \ + param(bool, error_capture, true, 0600) \ + param(bool, disable_display, false, 0400) \ + param(bool, verbose_state_checks, true, 0) \ + param(bool, nuclear_pageflip, false, 0400) \ + param(bool, enable_dp_mst, true, 0600) \ + param(bool, enable_gvt, false, 0400) #define MEMBER(T, member, ...) T member; struct i915_params { From a267ab8dec061c5a379a75a4c4f8206c63d87db9 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 5 Dec 2019 17:43:41 +0200 Subject: [PATCH 0027/1537] drm/i915/params: support bool values for int and uint params It's not uncommon for us to switch param types between bools and ints, often having otherwise bool semantics but -1 value for platform default. Allow bool values (such as YyNn) for ints. Reviewed-by: Chris Wilson Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/c945ac7b08e0eb0827cf647609885f4abdb84f1d.1575560168.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_debugfs_params.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_debugfs_params.c b/drivers/gpu/drm/i915/i915_debugfs_params.c index 7f1af5a35ca1..12cbdbdf4d80 100644 --- a/drivers/gpu/drm/i915/i915_debugfs_params.c +++ b/drivers/gpu/drm/i915/i915_debugfs_params.c @@ -32,6 +32,14 @@ static ssize_t i915_param_int_write(struct file *file, int ret; ret = kstrtoint_from_user(ubuf, len, 0, value); + if (ret) { + /* support boolean values too */ + bool b; + + ret = kstrtobool_from_user(ubuf, len, &b); + if (!ret) + *value = b; + } return ret ?: len; } @@ -77,6 +85,14 @@ static ssize_t i915_param_uint_write(struct file *file, int ret; ret = kstrtouint_from_user(ubuf, len, 0, value); + if (ret) { + /* support boolean values too */ + bool b; + + ret = kstrtobool_from_user(ubuf, len, &b); + if (!ret) + *value = b; + } return ret ?: len; } From 72ff2b8d5f2dcb09bfa37b902c23311eec426496 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 15 Jan 2020 12:25:09 +0000 Subject: [PATCH 0028/1537] drm/i915/gt: Use the BIT when checking the flags, not the index In converting over to using set_bit()/test_bit(), when manually inspecting the rq->fence.flags, we need to use BIT(). Fixes: e1c31fb5dde3 ("drm/i915: Merge i915_request.flags with i915_request.fence.flags") Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: Matthew Auld Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20200115122509.2673075-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_lrc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index 9e430590fb3a..a8fe2f16c910 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -1535,7 +1535,8 @@ static bool can_merge_rq(const struct i915_request *prev, return true; if (unlikely((prev->fence.flags ^ next->fence.flags) & - (I915_FENCE_FLAG_NOPREEMPT | I915_FENCE_FLAG_SENTINEL))) + (BIT(I915_FENCE_FLAG_NOPREEMPT) | + BIT(I915_FENCE_FLAG_SENTINEL)))) return false; if (!can_merge_ctx(prev->context, next->context)) From 9ecc6eabd8fee0972de3f23bd66d1a54b1781fa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 13 Dec 2019 15:34:50 +0200 Subject: [PATCH 0029/1537] drm/i915/fbc: Move the plane state check into the fbc functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of dealing with the presence/absence of the primary plane in the higher level pre/post plane update code let's move all that into the fbc code itself. Now the higher level code doesn't have to think about FBC details anymore. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20191213133453.22152-3-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/display/intel_display.c | 26 +++---------- drivers/gpu/drm/i915/display/intel_fbc.c | 40 +++++++++++++++----- drivers/gpu/drm/i915/display/intel_fbc.h | 13 +++---- 3 files changed, 42 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index aa0ece27186c..dd03987cc24f 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -6382,13 +6382,10 @@ static void intel_post_plane_update(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(state->base.dev); - struct intel_plane *primary = to_intel_plane(crtc->base.primary); const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); - const struct intel_plane_state *new_primary_state = - intel_atomic_get_new_plane_state(state, primary); enum pipe pipe = crtc->pipe; intel_frontbuffer_flip(dev_priv, new_crtc_state->fb_bits); @@ -6399,8 +6396,7 @@ static void intel_post_plane_update(struct intel_atomic_state *state, if (hsw_post_update_enable_ips(old_crtc_state, new_crtc_state)) hsw_enable_ips(new_crtc_state); - if (new_primary_state) - intel_fbc_post_update(crtc); + intel_fbc_post_update(state, crtc); if (needs_nv12_wa(old_crtc_state) && !needs_nv12_wa(new_crtc_state)) @@ -6415,20 +6411,16 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(state->base.dev); - struct intel_plane *primary = to_intel_plane(crtc->base.primary); const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); - const struct intel_plane_state *new_primary_state = - intel_atomic_get_new_plane_state(state, primary); enum pipe pipe = crtc->pipe; if (hsw_pre_update_disable_ips(old_crtc_state, new_crtc_state)) hsw_disable_ips(old_crtc_state); - if (new_primary_state && - intel_fbc_pre_update(crtc, new_crtc_state, new_primary_state)) + if (intel_fbc_pre_update(state, crtc)) intel_wait_for_vblank(dev_priv, pipe); /* Display WA 827 */ @@ -14857,9 +14849,6 @@ static void intel_update_crtc(struct intel_crtc *crtc, { struct drm_i915_private *dev_priv = to_i915(state->base.dev); bool modeset = needs_modeset(new_crtc_state); - struct intel_plane_state *new_plane_state = - intel_atomic_get_new_plane_state(state, - to_intel_plane(crtc->base.primary)); if (modeset) { intel_crtc_update_active_timings(new_crtc_state); @@ -14882,8 +14871,8 @@ static void intel_update_crtc(struct intel_crtc *crtc, if (new_crtc_state->update_pipe && !new_crtc_state->enable_fbc) intel_fbc_disable(crtc); - else if (new_plane_state) - intel_fbc_enable(crtc, new_crtc_state, new_plane_state); + else + intel_fbc_enable(state, crtc); /* Perform vblank evasion around commit operation */ intel_pipe_update_start(new_crtc_state); @@ -15045,15 +15034,12 @@ static void intel_post_crtc_enable_updates(struct intel_crtc *crtc, intel_atomic_get_new_crtc_state(state, crtc); struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); - struct intel_plane_state *new_plane_state = - intel_atomic_get_new_plane_state(state, - to_intel_plane(crtc->base.primary)); bool modeset = needs_modeset(new_crtc_state); if (new_crtc_state->update_pipe && !new_crtc_state->enable_fbc) intel_fbc_disable(crtc); - else if (new_plane_state) - intel_fbc_enable(crtc, new_crtc_state, new_plane_state); + else + intel_fbc_enable(state, crtc); /* Perform vblank evasion around commit operation */ intel_pipe_update_start(new_crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index a1048ece541e..42504e6353d5 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -867,10 +867,14 @@ static bool intel_fbc_can_flip_nuke(const struct intel_crtc_state *crtc_state) return true; } -bool intel_fbc_pre_update(struct intel_crtc *crtc, - const struct intel_crtc_state *crtc_state, - const struct intel_plane_state *plane_state) +bool intel_fbc_pre_update(struct intel_atomic_state *state, + struct intel_crtc *crtc) { + struct intel_plane *plane = to_intel_plane(crtc->base.primary); + const struct intel_crtc_state *crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); + const struct intel_plane_state *plane_state = + intel_atomic_get_new_plane_state(state, plane); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_fbc *fbc = &dev_priv->fbc; const char *reason = "update pending"; @@ -879,6 +883,9 @@ bool intel_fbc_pre_update(struct intel_crtc *crtc, if (!fbc_supported(dev_priv)) return need_vblank_wait; + if (!plane_state) + return need_vblank_wait; + mutex_lock(&fbc->lock); if (fbc->crtc != crtc) @@ -967,14 +974,21 @@ static void __intel_fbc_post_update(struct intel_crtc *crtc) intel_fbc_deactivate(dev_priv, "frontbuffer write"); } -void intel_fbc_post_update(struct intel_crtc *crtc) +void intel_fbc_post_update(struct intel_atomic_state *state, + struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_plane *plane = to_intel_plane(crtc->base.primary); + const struct intel_plane_state *plane_state = + intel_atomic_get_new_plane_state(state, plane); struct intel_fbc *fbc = &dev_priv->fbc; if (!fbc_supported(dev_priv)) return; + if (!plane_state) + return; + mutex_lock(&fbc->lock); __intel_fbc_post_update(crtc); mutex_unlock(&fbc->lock); @@ -1107,18 +1121,24 @@ void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv, * intel_fbc_enable multiple times for the same pipe without an * intel_fbc_disable in the middle, as long as it is deactivated. */ -void intel_fbc_enable(struct intel_crtc *crtc, - const struct intel_crtc_state *crtc_state, - const struct intel_plane_state *plane_state) +void intel_fbc_enable(struct intel_atomic_state *state, + struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_plane *plane = to_intel_plane(crtc->base.primary); + const struct intel_crtc_state *crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); + const struct intel_plane_state *plane_state = + intel_atomic_get_new_plane_state(state, plane); struct intel_fbc *fbc = &dev_priv->fbc; struct intel_fbc_state_cache *cache = &fbc->state_cache; - const struct drm_framebuffer *fb = plane_state->hw.fb; if (!fbc_supported(dev_priv)) return; + if (!plane_state) + return; + mutex_lock(&fbc->lock); if (fbc->crtc) { @@ -1139,14 +1159,14 @@ void intel_fbc_enable(struct intel_crtc *crtc, if (intel_fbc_alloc_cfb(dev_priv, intel_fbc_calculate_cfb_size(dev_priv, cache), - fb->format->cpp[0])) { + plane_state->hw.fb->format->cpp[0])) { cache->plane.visible = false; fbc->no_fbc_reason = "not enough stolen memory"; goto out; } if ((IS_GEN9_BC(dev_priv) || IS_BROXTON(dev_priv)) && - fb->modifier != I915_FORMAT_MOD_X_TILED) + plane_state->hw.fb->modifier != I915_FORMAT_MOD_X_TILED) cache->gen9_wa_cfb_stride = DIV_ROUND_UP(cache->plane.src_w, 32 * fbc->threshold) * 8; else diff --git a/drivers/gpu/drm/i915/display/intel_fbc.h b/drivers/gpu/drm/i915/display/intel_fbc.h index c8a5e5098687..6dc1edefe81b 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.h +++ b/drivers/gpu/drm/i915/display/intel_fbc.h @@ -19,14 +19,13 @@ struct intel_plane_state; void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv, struct intel_atomic_state *state); bool intel_fbc_is_active(struct drm_i915_private *dev_priv); -bool intel_fbc_pre_update(struct intel_crtc *crtc, - const struct intel_crtc_state *crtc_state, - const struct intel_plane_state *plane_state); -void intel_fbc_post_update(struct intel_crtc *crtc); +bool intel_fbc_pre_update(struct intel_atomic_state *state, + struct intel_crtc *crtc); +void intel_fbc_post_update(struct intel_atomic_state *state, + struct intel_crtc *crtc); void intel_fbc_init(struct drm_i915_private *dev_priv); -void intel_fbc_enable(struct intel_crtc *crtc, - const struct intel_crtc_state *crtc_state, - const struct intel_plane_state *plane_state); +void intel_fbc_enable(struct intel_atomic_state *state, + struct intel_crtc *crtc); void intel_fbc_disable(struct intel_crtc *crtc); void intel_fbc_global_disable(struct drm_i915_private *dev_priv); void intel_fbc_invalidate(struct drm_i915_private *dev_priv, From 661d6ec00058b11eae0ff0db198aafc9a2166b19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 13 Dec 2019 15:34:51 +0200 Subject: [PATCH 0030/1537] drm/i915/fbc: Nuke fbc_supported() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fbc_supported() is just a pointless wrapper for HAS_FBC(). Get rid of it. In places where we're operating on a specific plane we can replace this with a plane->has_fbc check to avoid doing anything for crtcs that don't even support fbc. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20191213133453.22152-4-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/display/intel_fbc.c | 33 +++++++----------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 42504e6353d5..28adf4636800 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -45,11 +45,6 @@ #include "intel_fbc.h" #include "intel_frontbuffer.h" -static inline bool fbc_supported(struct drm_i915_private *dev_priv) -{ - return HAS_FBC(dev_priv); -} - /* * In some platforms where the CRTC's x:0/y:0 coordinates doesn't match the * frontbuffer's x:0/y:0 coordinates we lie to the hardware about the plane's @@ -543,7 +538,7 @@ void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv) { struct intel_fbc *fbc = &dev_priv->fbc; - if (!fbc_supported(dev_priv)) + if (!HAS_FBC(dev_priv)) return; mutex_lock(&fbc->lock); @@ -880,10 +875,7 @@ bool intel_fbc_pre_update(struct intel_atomic_state *state, const char *reason = "update pending"; bool need_vblank_wait = false; - if (!fbc_supported(dev_priv)) - return need_vblank_wait; - - if (!plane_state) + if (!plane->has_fbc || !plane_state) return need_vblank_wait; mutex_lock(&fbc->lock); @@ -983,10 +975,7 @@ void intel_fbc_post_update(struct intel_atomic_state *state, intel_atomic_get_new_plane_state(state, plane); struct intel_fbc *fbc = &dev_priv->fbc; - if (!fbc_supported(dev_priv)) - return; - - if (!plane_state) + if (!plane->has_fbc || !plane_state) return; mutex_lock(&fbc->lock); @@ -1008,7 +997,7 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv, { struct intel_fbc *fbc = &dev_priv->fbc; - if (!fbc_supported(dev_priv)) + if (!HAS_FBC(dev_priv)) return; if (origin == ORIGIN_GTT || origin == ORIGIN_FLIP) @@ -1029,7 +1018,7 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv, { struct intel_fbc *fbc = &dev_priv->fbc; - if (!fbc_supported(dev_priv)) + if (!HAS_FBC(dev_priv)) return; mutex_lock(&fbc->lock); @@ -1133,10 +1122,7 @@ void intel_fbc_enable(struct intel_atomic_state *state, struct intel_fbc *fbc = &dev_priv->fbc; struct intel_fbc_state_cache *cache = &fbc->state_cache; - if (!fbc_supported(dev_priv)) - return; - - if (!plane_state) + if (!plane->has_fbc || !plane_state) return; mutex_lock(&fbc->lock); @@ -1189,9 +1175,10 @@ void intel_fbc_enable(struct intel_atomic_state *state, void intel_fbc_disable(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_plane *plane = to_intel_plane(crtc->base.primary); struct intel_fbc *fbc = &dev_priv->fbc; - if (!fbc_supported(dev_priv)) + if (!plane->has_fbc) return; mutex_lock(&fbc->lock); @@ -1210,7 +1197,7 @@ void intel_fbc_global_disable(struct drm_i915_private *dev_priv) { struct intel_fbc *fbc = &dev_priv->fbc; - if (!fbc_supported(dev_priv)) + if (!HAS_FBC(dev_priv)) return; mutex_lock(&fbc->lock); @@ -1287,7 +1274,7 @@ void intel_fbc_handle_fifo_underrun_irq(struct drm_i915_private *dev_priv) { struct intel_fbc *fbc = &dev_priv->fbc; - if (!fbc_supported(dev_priv)) + if (!HAS_FBC(dev_priv)) return; /* There's no guarantee that underrun_detected won't be set to true From d54151c5c8c08e2cbb88d62643a9c9c8d9e5f367 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 13 Dec 2019 15:34:52 +0200 Subject: [PATCH 0031/1537] drm/i915/fbc: Add fbc tracepoints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add tracepoints which let us know when fbc activates/deactivates/nukes. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20191213133453.22152-5-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/display/intel_fbc.c | 9 ++++ drivers/gpu/drm/i915/i915_trace.h | 62 ++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 28adf4636800..88a9c2fea695 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -41,6 +41,7 @@ #include #include "i915_drv.h" +#include "i915_trace.h" #include "intel_display_types.h" #include "intel_fbc.h" #include "intel_frontbuffer.h" @@ -200,6 +201,10 @@ static bool g4x_fbc_is_active(struct drm_i915_private *dev_priv) /* This function forces a CFB recompression through the nuke operation. */ static void intel_fbc_recompress(struct drm_i915_private *dev_priv) { + struct intel_fbc *fbc = &dev_priv->fbc; + + trace_intel_fbc_nuke(fbc->crtc); + I915_WRITE(MSG_FBC_REND_STATE, FBC_REND_NUKE); POSTING_READ(MSG_FBC_REND_STATE); } @@ -356,6 +361,8 @@ static void intel_fbc_hw_activate(struct drm_i915_private *dev_priv) { struct intel_fbc *fbc = &dev_priv->fbc; + trace_intel_fbc_activate(fbc->crtc); + fbc->active = true; fbc->activated = true; @@ -373,6 +380,8 @@ static void intel_fbc_hw_deactivate(struct drm_i915_private *dev_priv) { struct intel_fbc *fbc = &dev_priv->fbc; + trace_intel_fbc_deactivate(fbc->crtc); + fbc->active = false; if (INTEL_GEN(dev_priv) >= 5) diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 233a97a2c276..162c76a9d1e8 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -339,6 +339,68 @@ TRACE_EVENT(intel_disable_plane, __entry->frame, __entry->scanline) ); +/* fbc */ + +TRACE_EVENT(intel_fbc_activate, + TP_PROTO(struct intel_crtc *crtc), + TP_ARGS(crtc), + + TP_STRUCT__entry( + __field(enum pipe, pipe) + __field(u32, frame) + __field(u32, scanline) + ), + + TP_fast_assign( + __entry->pipe = crtc->pipe; + __entry->frame = intel_crtc_get_vblank_counter(crtc); + __entry->scanline = intel_get_crtc_scanline(crtc); + ), + + TP_printk("pipe %c, frame=%u, scanline=%u", + pipe_name(__entry->pipe), __entry->frame, __entry->scanline) +); + +TRACE_EVENT(intel_fbc_deactivate, + TP_PROTO(struct intel_crtc *crtc), + TP_ARGS(crtc), + + TP_STRUCT__entry( + __field(enum pipe, pipe) + __field(u32, frame) + __field(u32, scanline) + ), + + TP_fast_assign( + __entry->pipe = crtc->pipe; + __entry->frame = intel_crtc_get_vblank_counter(crtc); + __entry->scanline = intel_get_crtc_scanline(crtc); + ), + + TP_printk("pipe %c, frame=%u, scanline=%u", + pipe_name(__entry->pipe), __entry->frame, __entry->scanline) +); + +TRACE_EVENT(intel_fbc_nuke, + TP_PROTO(struct intel_crtc *crtc), + TP_ARGS(crtc), + + TP_STRUCT__entry( + __field(enum pipe, pipe) + __field(u32, frame) + __field(u32, scanline) + ), + + TP_fast_assign( + __entry->pipe = crtc->pipe; + __entry->frame = intel_crtc_get_vblank_counter(crtc); + __entry->scanline = intel_get_crtc_scanline(crtc); + ), + + TP_printk("pipe %c, frame=%u, scanline=%u", + pipe_name(__entry->pipe), __entry->frame, __entry->scanline) +); + /* pipe updates */ TRACE_EVENT(intel_pipe_update_start, From f78d5da6e7bd500df734bd1d5260f99ceee9d01f Mon Sep 17 00:00:00 2001 From: Radhakrishna Sripada Date: Thu, 9 Jan 2020 14:37:27 -0800 Subject: [PATCH 0032/1537] drm/i915/tgl: Add Wa_1409825376 to tgl Workaround database indicates we should disable VRH clockgating in pre-production hardware. V2: - Use REG_BIT macro - Update reference in commit message(Matt) Bspec: 52890 Bspec: 49424 Reviewed-by: Matt Roper Signed-off-by: Radhakrishna Sripada Signed-off-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20200109223727.5630-1-radhakrishna.sripada@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 3 +++ drivers/gpu/drm/i915/intel_pm.c | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index e5071af4a3b3..5e5949edf2a8 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4124,6 +4124,9 @@ enum { #define PWM2_GATING_DIS (1 << 14) #define PWM1_GATING_DIS (1 << 13) +#define GEN9_CLKGATE_DIS_3 _MMIO(0x46538) +#define TGL_VRH_GATING_DIS REG_BIT(31) + #define GEN9_CLKGATE_DIS_4 _MMIO(0x4653C) #define BXT_GMBUS_GATING_DIS (1 << 14) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index bd2d30ecc030..8e5f08c58b0c 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6663,6 +6663,11 @@ static void tgl_init_clock_gating(struct drm_i915_private *dev_priv) I915_WRITE(POWERGATE_ENABLE, I915_READ(POWERGATE_ENABLE) | vd_pg_enable); + + /* Wa_1409825376:tgl (pre-prod)*/ + if (IS_TGL_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_A0)) + I915_WRITE(GEN9_CLKGATE_DIS_3, I915_READ(GEN9_CLKGATE_DIS_3) | + TGL_VRH_GATING_DIS); } static void cnp_init_clock_gating(struct drm_i915_private *dev_priv) From d3d19d6fc5736a798b118971935ce274f7deaa82 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 13 Jan 2020 14:08:14 +0300 Subject: [PATCH 0033/1537] fbdev: potential information leak in do_fb_ioctl() The "fix" struct has a 2 byte hole after ->ywrapstep and the "fix = info->fix;" assignment doesn't necessarily clear it. It depends on the compiler. The solution is just to replace the assignment with an memcpy(). Fixes: 1f5e31d7e55a ("fbmem: don't call copy_from/to_user() with mutex held") Signed-off-by: Dan Carpenter Cc: Andrew Morton Cc: Arnd Bergmann Cc: "Eric W. Biederman" Cc: Andrea Righi Cc: Daniel Vetter Cc: Sam Ravnborg Cc: Maarten Lankhorst Cc: Daniel Thompson Cc: Peter Rosin Cc: Jani Nikula Cc: Gerd Hoffmann Signed-off-by: Bartlomiej Zolnierkiewicz Link: https://patchwork.freedesktop.org/patch/msgid/20200113100132.ixpaymordi24n3av@kili.mountain --- drivers/video/fbdev/core/fbmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index d04554959ea7..bb8d8dbc0461 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1115,7 +1115,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, break; case FBIOGET_FSCREENINFO: lock_fb_info(info); - fix = info->fix; + memcpy(&fix, &info->fix, sizeof(fix)); if (info->flags & FBINFO_HIDE_SMEM_START) fix.smem_start = 0; unlock_fb_info(info); From 366c5aa18c128966b1768805cb69e40bb92e9664 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 14 Nov 2019 17:27:20 +0000 Subject: [PATCH 0034/1537] video: hyperv_fb: fix indentation issue There is a block of statements that are indented too deeply, remove the extraneous tabs. Signed-off-by: Colin Ian King Reviewed-by: Michael Kelley Cc: "K . Y . Srinivasan" Cc: Haiyang Zhang Cc: Stephen Hemminger Cc: Sasha Levin [b.zolnierkie: minor patch summary fixup] Signed-off-by: Bartlomiej Zolnierkiewicz Link: https://patchwork.freedesktop.org/patch/msgid/20191114172720.322023-1-colin.king@canonical.com --- drivers/video/fbdev/hyperv_fb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c index afe9fd751cd5..3108a42db777 100644 --- a/drivers/video/fbdev/hyperv_fb.c +++ b/drivers/video/fbdev/hyperv_fb.c @@ -582,8 +582,8 @@ static int synthvid_get_supported_resolution(struct hv_device *hdev) t = wait_for_completion_timeout(&par->wait, VSP_TIMEOUT); if (!t) { pr_err("Time out on waiting resolution response\n"); - ret = -ETIMEDOUT; - goto out; + ret = -ETIMEDOUT; + goto out; } if (msg->resolution_resp.resolution_count == 0) { From ac0c2558161d7bf273fcf980d291eb338f47787b Mon Sep 17 00:00:00 2001 From: Chuhong Yuan Date: Mon, 18 Nov 2019 19:41:50 +0800 Subject: [PATCH 0035/1537] video: ssd1307fb: add the missed regulator_disable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver forgets to disable the regulator in remove like what is done in probe failure. Add the missed call to fix it. Signed-off-by: Chuhong Yuan Tested-by: Michal Vokáč Signed-off-by: Bartlomiej Zolnierkiewicz Link: https://patchwork.freedesktop.org/patch/msgid/20191118114150.25724-1-hslester96@gmail.com --- drivers/video/fbdev/ssd1307fb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c index 142535267fec..1a0bd78f9345 100644 --- a/drivers/video/fbdev/ssd1307fb.c +++ b/drivers/video/fbdev/ssd1307fb.c @@ -791,6 +791,8 @@ static int ssd1307fb_remove(struct i2c_client *client) pwm_disable(par->pwm); pwm_put(par->pwm); } + if (par->vbat_reg) + regulator_disable(par->vbat_reg); fb_deferred_io_cleanup(info); __free_pages(__va(info->fix.smem_start), get_order(info->fix.smem_len)); framebuffer_release(info); From 52733e95f040944531b6e29544c8494f8a302ff1 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 20 Nov 2019 21:38:38 +0800 Subject: [PATCH 0036/1537] video: Fix Kconfig indentation Adjust indentation from spaces to tab (+optional two spaces) as in coding style with command like: $ sed -e 's/^ /\t/' -i */Kconfig Signed-off-by: Krzysztof Kozlowski Cc: Jiri Kosina Cc: Lee Jones Cc: Daniel Thompson Cc: Jingoo Han Signed-off-by: Bartlomiej Zolnierkiewicz Link: https://patchwork.freedesktop.org/patch/msgid/20191120133838.13132-1-krzk@kernel.org --- drivers/video/backlight/Kconfig | 8 ++-- drivers/video/console/Kconfig | 76 ++++++++++++++++----------------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 403707a3e503..95e2000c1491 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -9,7 +9,7 @@ menu "Backlight & LCD device support" # LCD # config LCD_CLASS_DEVICE - tristate "Lowlevel LCD controls" + tristate "Lowlevel LCD controls" help This framework adds support for low-level control of LCD. Some framebuffer devices connect to platform-specific LCD modules @@ -141,10 +141,10 @@ endif # LCD_CLASS_DEVICE # Backlight # config BACKLIGHT_CLASS_DEVICE - tristate "Lowlevel Backlight controls" + tristate "Lowlevel Backlight controls" help This framework adds support for low-level control of the LCD - backlight. This includes support for brightness and power. + backlight. This includes support for brightness and power. To have support for your specific LCD panel you will have to select the proper drivers which depend on this option. @@ -272,7 +272,7 @@ config BACKLIGHT_APPLE tristate "Apple Backlight Driver" depends on X86 && ACPI help - If you have an Intel-based Apple say Y to enable a driver for its + If you have an Intel-based Apple say Y to enable a driver for its backlight. config BACKLIGHT_TOSA diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index c10e17fb9a9a..ac3a28c08f78 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -27,7 +27,7 @@ config VGACON_SOFT_SCROLLBACK depends on VGA_CONSOLE default n help - The scrollback buffer of the standard VGA console is located in + The scrollback buffer of the standard VGA console is located in the VGA RAM. The size of this RAM is fixed and is quite small. If you require a larger scrollback buffer, this can be placed in System RAM which is dynamically allocated during initialization. @@ -84,12 +84,12 @@ config MDA_CONSOLE If unsure, say N. config SGI_NEWPORT_CONSOLE - tristate "SGI Newport Console support" + tristate "SGI Newport Console support" depends on SGI_IP22 && HAS_IOMEM - select FONT_SUPPORT - help - Say Y here if you want the console on the Newport aka XL graphics - card of your Indy. Most people say Y here. + select FONT_SUPPORT + help + Say Y here if you want the console on the Newport aka XL graphics + card of your Indy. Most people say Y here. config DUMMY_CONSOLE bool @@ -97,24 +97,24 @@ config DUMMY_CONSOLE default y config DUMMY_CONSOLE_COLUMNS - int "Initial number of console screen columns" - depends on DUMMY_CONSOLE && !ARM - default 160 if PARISC - default 80 - help - On PA-RISC, the default value is 160, which should fit a 1280x1024 - monitor. - Select 80 if you use a 640x480 resolution by default. + int "Initial number of console screen columns" + depends on DUMMY_CONSOLE && !ARM + default 160 if PARISC + default 80 + help + On PA-RISC, the default value is 160, which should fit a 1280x1024 + monitor. + Select 80 if you use a 640x480 resolution by default. config DUMMY_CONSOLE_ROWS - int "Initial number of console screen rows" - depends on DUMMY_CONSOLE && !ARM - default 64 if PARISC - default 25 - help - On PA-RISC, the default value is 64, which should fit a 1280x1024 - monitor. - Select 25 if you use a 640x480 resolution by default. + int "Initial number of console screen rows" + depends on DUMMY_CONSOLE && !ARM + default 64 if PARISC + default 25 + help + On PA-RISC, the default value is 64, which should fit a 1280x1024 + monitor. + Select 25 if you use a 640x480 resolution by default. config FRAMEBUFFER_CONSOLE bool "Framebuffer Console support" @@ -130,11 +130,11 @@ config FRAMEBUFFER_CONSOLE_DETECT_PRIMARY depends on FRAMEBUFFER_CONSOLE default n ---help--- - If this option is selected, the framebuffer console will - automatically select the primary display device (if the architecture + If this option is selected, the framebuffer console will + automatically select the primary display device (if the architecture supports this feature). Otherwise, the framebuffer console will - always select the first framebuffer driver that is loaded. The latter - is the default behavior. + always select the first framebuffer driver that is loaded. The latter + is the default behavior. You can always override the automatic selection of the primary device by using the fbcon=map: boot option. @@ -145,11 +145,11 @@ config FRAMEBUFFER_CONSOLE_ROTATION bool "Framebuffer Console Rotation" depends on FRAMEBUFFER_CONSOLE help - Enable display rotation for the framebuffer console. This is done - in software and may be significantly slower than a normally oriented - display. Note that the rotation is done at the console level only - such that other users of the framebuffer will remain normally - oriented. + Enable display rotation for the framebuffer console. This is done + in software and may be significantly slower than a normally oriented + display. Note that the rotation is done at the console level only + such that other users of the framebuffer will remain normally + oriented. config FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER bool "Framebuffer Console Deferred Takeover" @@ -163,14 +163,14 @@ config FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER black screen as soon as fbcon loads. config STI_CONSOLE - bool "STI text console" + bool "STI text console" depends on PARISC && HAS_IOMEM - select FONT_SUPPORT - default y - help - The STI console is the builtin display/keyboard on HP-PARISC - machines. Say Y here to build support for it into your kernel. - The alternative is to use your primary serial port as a console. + select FONT_SUPPORT + default y + help + The STI console is the builtin display/keyboard on HP-PARISC + machines. Say Y here to build support for it into your kernel. + The alternative is to use your primary serial port as a console. endmenu From bc5e36f3d2cef45331aed822e2c4608634df256b Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 4 Dec 2019 15:28:47 +0000 Subject: [PATCH 0037/1537] OMAP: DSS2: remove non-zero check on variable r Variable r is being initialized to zero, so the check of a non-zero rv is redundant and can be removed. It appears that the previous case statements set r to be -EINVAL and the "Fallthrough" comment afterwards suggested it was going to fall through to this non-zero check but won't because of the break statement. Remove the confusion by removing the Fallthrough comment too. Addresses-Coverity: ("Logically dead code") Fixes: b39a982ddecf ("OMAP: DSS2: omapfb driver") Signed-off-by: Colin Ian King Signed-off-by: Bartlomiej Zolnierkiewicz Link: https://patchwork.freedesktop.org/patch/msgid/20191204152847.1435188-1-colin.king@canonical.com --- drivers/video/fbdev/omap2/omapfb/omapfb-main.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c index 8dfa9158ba78..836e7b1639ce 100644 --- a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c +++ b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c @@ -1154,16 +1154,12 @@ static int _setcolreg(struct fb_info *fbi, u_int regno, u_int red, u_int green, r = fbdev->ctrl->setcolreg(regno, red, green, blue, transp, update_hw_pal); */ - /* Fallthrough */ r = -EINVAL; break; case OMAPFB_COLOR_RGB565: case OMAPFB_COLOR_RGB444: case OMAPFB_COLOR_RGB24P: case OMAPFB_COLOR_RGB24U: - if (r != 0) - break; - if (regno < 16) { u32 pal; pal = ((red >> (16 - var->red.length)) << From 28388b3325e3fe21faed85280d12bb68c2ff63fc Mon Sep 17 00:00:00 2001 From: Chuhong Yuan Date: Fri, 6 Dec 2019 00:06:13 +0800 Subject: [PATCH 0038/1537] pxa168fb: fix release function mismatch in probe failure The driver uses kfree() to release the resource allocated by framebuffer_alloc(), which does not match. Use framebuffer_release() instead to fix it. Fixes: 638772c7553f ("fb: add support of LCD display controller on pxa168/910 (base layer)") Signed-off-by: Chuhong Yuan Signed-off-by: Bartlomiej Zolnierkiewicz Link: https://patchwork.freedesktop.org/patch/msgid/20191205160613.32075-1-hslester96@gmail.com --- drivers/video/fbdev/pxa168fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/pxa168fb.c b/drivers/video/fbdev/pxa168fb.c index 362d3dfe8287..3679698fffd1 100644 --- a/drivers/video/fbdev/pxa168fb.c +++ b/drivers/video/fbdev/pxa168fb.c @@ -769,7 +769,7 @@ static int pxa168fb_probe(struct platform_device *pdev) dma_free_wc(fbi->dev, info->fix.smem_len, info->screen_base, fbi->fb_start_dma); failed_free_info: - kfree(info); + framebuffer_release(info); dev_err(&pdev->dev, "frame buffer device init failed with %d\n", ret); return ret; From 2be24502158b30fe0d7d79e8090184776e1501c6 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 17 Dec 2019 19:53:37 -0700 Subject: [PATCH 0039/1537] fbcon: Adjust indentation in set_con2fb_map Clang warns: ../drivers/video/fbdev/core/fbcon.c:915:3: warning: misleading indentation; statement is not part of the previous 'if' [-Wmisleading-indentation] return err; ^ ../drivers/video/fbdev/core/fbcon.c:912:2: note: previous statement is here if (!search_fb_in_map(info_idx)) ^ 1 warning generated. This warning occurs because there is a space before the tab on this line. This happens on several lines in this function; normalize them so that the indentation is consistent with the Linux kernel coding style and clang no longer warns. This warning was introduced before the beginning of git history so no fixes tab. Link: https://github.com/ClangBuiltLinux/linux/issues/824 Signed-off-by: Nathan Chancellor Reviewed-by: Nick Desaulniers Signed-off-by: Bartlomiej Zolnierkiewicz Link: https://patchwork.freedesktop.org/patch/msgid/20191218025337.35044-1-natechancellor@gmail.com --- drivers/video/fbdev/core/fbcon.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index bb6ae995c2e5..28335788e76e 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -873,7 +873,7 @@ static int set_con2fb_map(int unit, int newidx, int user) int oldidx = con2fb_map[unit]; struct fb_info *info = registered_fb[newidx]; struct fb_info *oldinfo = NULL; - int found, err = 0; + int found, err = 0; WARN_CONSOLE_UNLOCKED(); @@ -895,31 +895,30 @@ static int set_con2fb_map(int unit, int newidx, int user) con2fb_map[unit] = newidx; if (!err && !found) - err = con2fb_acquire_newinfo(vc, info, unit, oldidx); - + err = con2fb_acquire_newinfo(vc, info, unit, oldidx); /* * If old fb is not mapped to any of the consoles, * fbcon should release it. */ - if (!err && oldinfo && !search_fb_in_map(oldidx)) - err = con2fb_release_oldinfo(vc, oldinfo, info, unit, oldidx, - found); + if (!err && oldinfo && !search_fb_in_map(oldidx)) + err = con2fb_release_oldinfo(vc, oldinfo, info, unit, oldidx, + found); - if (!err) { - int show_logo = (fg_console == 0 && !user && - logo_shown != FBCON_LOGO_DONTSHOW); + if (!err) { + int show_logo = (fg_console == 0 && !user && + logo_shown != FBCON_LOGO_DONTSHOW); - if (!found) - fbcon_add_cursor_timer(info); - con2fb_map_boot[unit] = newidx; - con2fb_init_display(vc, info, unit, show_logo); + if (!found) + fbcon_add_cursor_timer(info); + con2fb_map_boot[unit] = newidx; + con2fb_init_display(vc, info, unit, show_logo); } if (!search_fb_in_map(info_idx)) info_idx = newidx; - return err; + return err; } /* From 93166f5f2e4dc593cff8ca77ef828ac6f148b0f3 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 17 Dec 2019 20:00:25 -0700 Subject: [PATCH 0040/1537] fbmem: Adjust indentation in fb_prepare_logo and fb_blank Clang warns: ../drivers/video/fbdev/core/fbmem.c:665:3: warning: misleading indentation; statement is not part of the previous 'else' [-Wmisleading-indentation] if (fb_logo.depth > 4 && depth > 4) { ^ ../drivers/video/fbdev/core/fbmem.c:661:2: note: previous statement is here else ^ ../drivers/video/fbdev/core/fbmem.c:1075:3: warning: misleading indentation; statement is not part of the previous 'if' [-Wmisleading-indentation] return ret; ^ ../drivers/video/fbdev/core/fbmem.c:1072:2: note: previous statement is here if (!ret) ^ 2 warnings generated. This warning occurs because there are spaces before the tabs on these lines. Normalize the indentation in these functions so that it is consistent with the Linux kernel coding style and clang no longer warns. Fixes: 1692b37c99d5 ("fbdev: Fix logo if logo depth is less than framebuffer depth") Link: https://github.com/ClangBuiltLinux/linux/issues/825 Signed-off-by: Nathan Chancellor Reviewed-by: Nick Desaulniers Signed-off-by: Bartlomiej Zolnierkiewicz Link: https://patchwork.freedesktop.org/patch/msgid/20191218030025.10064-1-natechancellor@gmail.com --- drivers/video/fbdev/core/fbmem.c | 36 ++++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index bb8d8dbc0461..30e73ec4ad5c 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -663,20 +663,20 @@ int fb_prepare_logo(struct fb_info *info, int rotate) fb_logo.depth = 1; - if (fb_logo.depth > 4 && depth > 4) { - switch (info->fix.visual) { - case FB_VISUAL_TRUECOLOR: - fb_logo.needs_truepalette = 1; - break; - case FB_VISUAL_DIRECTCOLOR: - fb_logo.needs_directpalette = 1; - fb_logo.needs_cmapreset = 1; - break; - case FB_VISUAL_PSEUDOCOLOR: - fb_logo.needs_cmapreset = 1; - break; - } - } + if (fb_logo.depth > 4 && depth > 4) { + switch (info->fix.visual) { + case FB_VISUAL_TRUECOLOR: + fb_logo.needs_truepalette = 1; + break; + case FB_VISUAL_DIRECTCOLOR: + fb_logo.needs_directpalette = 1; + fb_logo.needs_cmapreset = 1; + break; + case FB_VISUAL_PSEUDOCOLOR: + fb_logo.needs_cmapreset = 1; + break; + } + } height = fb_logo.logo->height; if (fb_center_logo) @@ -1065,19 +1065,19 @@ fb_blank(struct fb_info *info, int blank) struct fb_event event; int ret = -EINVAL; - if (blank > FB_BLANK_POWERDOWN) - blank = FB_BLANK_POWERDOWN; + if (blank > FB_BLANK_POWERDOWN) + blank = FB_BLANK_POWERDOWN; event.info = info; event.data = ␣ if (info->fbops->fb_blank) - ret = info->fbops->fb_blank(blank, info); + ret = info->fbops->fb_blank(blank, info); if (!ret) fb_notifier_call_chain(FB_EVENT_BLANK, &event); - return ret; + return ret; } EXPORT_SYMBOL(fb_blank); From 3c3c56397d5840d0e33eda1707625ecfc4d265a2 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 1 Jan 2020 08:43:25 +0100 Subject: [PATCH 0041/1537] video: sa1100fb: constify copied structure The monspecs structure is only copied into another structure, so make it const. The opportunity for this change was found using Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Bartlomiej Zolnierkiewicz Link: https://patchwork.freedesktop.org/patch/msgid/1577864614-5543-8-git-send-email-Julia.Lawall@inria.fr --- drivers/video/fbdev/sa1100fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/sa1100fb.c b/drivers/video/fbdev/sa1100fb.c index 5bb653db0cec..2d285cc384cf 100644 --- a/drivers/video/fbdev/sa1100fb.c +++ b/drivers/video/fbdev/sa1100fb.c @@ -1053,7 +1053,7 @@ static int sa1100fb_map_video_memory(struct sa1100fb_info *fbi) } /* Fake monspecs to fill in fbinfo structure */ -static struct fb_monspecs monspecs = { +static const struct fb_monspecs monspecs = { .hfmin = 30000, .hfmax = 70000, .vfmin = 50, From 091be7245a0393c1e6785f4b82cc88cc1445285b Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 1 Jan 2020 18:49:43 +0100 Subject: [PATCH 0042/1537] fbdev: s1d13xxxfb: use resource_size Use resource_size rather than a verbose computation on the end and start fields. The semantic patch that makes these changes is as follows: (http://coccinelle.lip6.fr/) @@ struct resource ptr; @@ - (ptr.end - ptr.start + 1) + resource_size(&ptr) Signed-off-by: Julia Lawall Cc: Kristoffer Ericson [b.zolnierkie: ported patch to drm-misc-next] Signed-off-by: Bartlomiej Zolnierkiewicz Link: https://patchwork.freedesktop.org/patch/msgid/1577900990-8588-4-git-send-email-Julia.Lawall@inria.fr --- drivers/video/fbdev/s1d13xxxfb.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/video/fbdev/s1d13xxxfb.c b/drivers/video/fbdev/s1d13xxxfb.c index e04efb567b5c..c23defa27036 100644 --- a/drivers/video/fbdev/s1d13xxxfb.c +++ b/drivers/video/fbdev/s1d13xxxfb.c @@ -746,9 +746,9 @@ s1d13xxxfb_remove(struct platform_device *pdev) } release_mem_region(pdev->resource[0].start, - pdev->resource[0].end - pdev->resource[0].start +1); + resource_size(&pdev->resource[0])); release_mem_region(pdev->resource[1].start, - pdev->resource[1].end - pdev->resource[1].start +1); + resource_size(&pdev->resource[1])); return 0; } @@ -788,14 +788,14 @@ static int s1d13xxxfb_probe(struct platform_device *pdev) } if (!request_mem_region(pdev->resource[0].start, - pdev->resource[0].end - pdev->resource[0].start +1, "s1d13xxxfb mem")) { + resource_size(&pdev->resource[0]), "s1d13xxxfb mem")) { dev_dbg(&pdev->dev, "request_mem_region failed\n"); ret = -EBUSY; goto bail; } if (!request_mem_region(pdev->resource[1].start, - pdev->resource[1].end - pdev->resource[1].start +1, "s1d13xxxfb regs")) { + resource_size(&pdev->resource[1]), "s1d13xxxfb regs")) { dev_dbg(&pdev->dev, "request_mem_region failed\n"); ret = -EBUSY; goto bail; @@ -810,7 +810,7 @@ static int s1d13xxxfb_probe(struct platform_device *pdev) platform_set_drvdata(pdev, info); default_par = info->par; default_par->regs = ioremap_nocache(pdev->resource[1].start, - pdev->resource[1].end - pdev->resource[1].start +1); + resource_size(&pdev->resource[1])); if (!default_par->regs) { printk(KERN_ERR PFX "unable to map registers\n"); ret = -ENOMEM; @@ -819,8 +819,7 @@ static int s1d13xxxfb_probe(struct platform_device *pdev) info->pseudo_palette = default_par->pseudo_palette; info->screen_base = ioremap_nocache(pdev->resource[0].start, - pdev->resource[0].end - pdev->resource[0].start +1); - + resource_size(&pdev->resource[0])); if (!info->screen_base) { printk(KERN_ERR PFX "unable to map framebuffer\n"); ret = -ENOMEM; @@ -857,9 +856,9 @@ static int s1d13xxxfb_probe(struct platform_device *pdev) info->fix = s1d13xxxfb_fix; info->fix.mmio_start = pdev->resource[1].start; - info->fix.mmio_len = pdev->resource[1].end - pdev->resource[1].start + 1; + info->fix.mmio_len = resource_size(&pdev->resource[1]); info->fix.smem_start = pdev->resource[0].start; - info->fix.smem_len = pdev->resource[0].end - pdev->resource[0].start + 1; + info->fix.smem_len = resource_size(&pdev->resource[0]); printk(KERN_INFO PFX "regs mapped at 0x%p, fb %d KiB mapped at 0x%p\n", default_par->regs, info->fix.smem_len / 1024, info->screen_base); From 44a391081c9b186cb1b3846c7f1bb5f75afa3253 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 1 Jan 2020 18:49:47 +0100 Subject: [PATCH 0043/1537] fbdev: cg14fb: use resource_size Use resource_size rather than a verbose computation on the end and start fields. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) @@ struct resource ptr; @@ - (ptr.end - ptr.start + 1) + resource_size(&ptr) Signed-off-by: Julia Lawall [b.zolnierkie: minor patch summary fixup] Signed-off-by: Bartlomiej Zolnierkiewicz Link: https://patchwork.freedesktop.org/patch/msgid/1577900990-8588-8-git-send-email-Julia.Lawall@inria.fr --- drivers/video/fbdev/cg14.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/video/fbdev/cg14.c b/drivers/video/fbdev/cg14.c index a620b51cf7d0..6a745eb46ca1 100644 --- a/drivers/video/fbdev/cg14.c +++ b/drivers/video/fbdev/cg14.c @@ -509,8 +509,7 @@ static int cg14_probe(struct platform_device *op) if (!par->regs || !par->clut || !par->cursor || !info->screen_base) goto out_unmap_regs; - is_8mb = (((op->resource[1].end - op->resource[1].start) + 1) == - (8 * 1024 * 1024)); + is_8mb = (resource_size(&op->resource[1]) == (8 * 1024 * 1024)); BUILD_BUG_ON(sizeof(par->mmap_map) != sizeof(__cg14_mmap_map)); From 914d66312d46d877f2d306c1c940ee52b525ba1e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sat, 4 Jan 2020 16:21:02 +0100 Subject: [PATCH 0044/1537] video: exynos: Rename Exynos to lowercase Fix up inconsistent usage of upper and lowercase letters in "Exynos" name. "EXYNOS" is not an abbreviation but a regular trademarked name. Therefore it should be written with lowercase letters starting with capital letter. The lowercase "Exynos" name is promoted by its manufacturer Samsung Electronics Co., Ltd., in advertisement materials and on website. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Bartlomiej Zolnierkiewicz Link: https://patchwork.freedesktop.org/patch/msgid/20200104152107.11407-16-krzk@kernel.org --- include/video/samsung_fimd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/video/samsung_fimd.h b/include/video/samsung_fimd.h index b6571c3cfa31..c4a93ce1de48 100644 --- a/include/video/samsung_fimd.h +++ b/include/video/samsung_fimd.h @@ -10,7 +10,7 @@ * * This is the register set for the fimd and new style framebuffer interface * found from the S3C2443 onwards into the S3C2416, S3C2450, the - * S3C64XX series such as the S3C6400 and S3C6410, and EXYNOS series. + * S3C64XX series such as the S3C6400 and S3C6410, and Exynos series. */ /* VIDCON0 */ From 31a2a3292139d620e2ecb469925ece2e67ced5ff Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 6 Jan 2020 17:13:52 +0900 Subject: [PATCH 0045/1537] fbdev: remove object duplication in Makefile The objects in $(fb-objs) $(fb-y) $(fb-m) are linked to fb.ko . This line adds $(fb-y) to fb-objs, so the objects from $(fb-y) are listed twice as the dependency of the module. It works because Kbuild trims the duplicated objects from linking, but there is no good reason to have this line. Signed-off-by: Masahiro Yamada Signed-off-by: Bartlomiej Zolnierkiewicz Link: https://patchwork.freedesktop.org/patch/msgid/20200106081352.27730-1-masahiroy@kernel.org --- drivers/video/fbdev/core/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/video/fbdev/core/Makefile b/drivers/video/fbdev/core/Makefile index 37710316a680..26cbc965497c 100644 --- a/drivers/video/fbdev/core/Makefile +++ b/drivers/video/fbdev/core/Makefile @@ -16,7 +16,6 @@ fb-y += fbcon_rotate.o fbcon_cw.o fbcon_ud.o \ fbcon_ccw.o endif endif -fb-objs := $(fb-y) obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o From e4eed858357a94438fa5e3c5839c7b597acdb688 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 13 Jan 2020 14:46:27 +0000 Subject: [PATCH 0046/1537] video: fbdev: nvidia: clean up indentation issues and comment block There is a hunk of code that is incorrectly indented, clean up the indentation and a comment block. Also remove block braces around a one line statement on an if condition and add missing spaces after if keywords. Signed-off-by: Colin Ian King Cc: Antonino Daplas Signed-off-by: Bartlomiej Zolnierkiewicz Link: https://patchwork.freedesktop.org/patch/msgid/20200113144627.219967-1-colin.king@canonical.com --- drivers/video/fbdev/nvidia/nvidia.c | 37 ++++++++++++++--------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/drivers/video/fbdev/nvidia/nvidia.c b/drivers/video/fbdev/nvidia/nvidia.c index c583c018304d..c24de9107958 100644 --- a/drivers/video/fbdev/nvidia/nvidia.c +++ b/drivers/video/fbdev/nvidia/nvidia.c @@ -168,27 +168,26 @@ static int nvidia_panel_tweak(struct nvidia_par *par, { int tweak = 0; - if (par->paneltweak) { - tweak = par->paneltweak; - } else { - /* begin flat panel hacks */ - /* This is unfortunate, but some chips need this register - tweaked or else you get artifacts where adjacent pixels are - swapped. There are no hard rules for what to set here so all - we can do is experiment and apply hacks. */ + if (par->paneltweak) { + tweak = par->paneltweak; + } else { + /* Begin flat panel hacks. + * This is unfortunate, but some chips need this register + * tweaked or else you get artifacts where adjacent pixels are + * swapped. There are no hard rules for what to set here so all + * we can do is experiment and apply hacks. + */ + if (((par->Chipset & 0xffff) == 0x0328) && (state->bpp == 32)) { + /* At least one NV34 laptop needs this workaround. */ + tweak = -1; + } - if(((par->Chipset & 0xffff) == 0x0328) && (state->bpp == 32)) { - /* At least one NV34 laptop needs this workaround. */ - tweak = -1; - } + if ((par->Chipset & 0xfff0) == 0x0310) + tweak = 1; + /* end flat panel hacks */ + } - if((par->Chipset & 0xfff0) == 0x0310) { - tweak = 1; - } - /* end flat panel hacks */ - } - - return tweak; + return tweak; } static void nvidia_screen_off(struct nvidia_par *par, int on) From f3c0efc9fe7a4e61544034f525348a3aa86ac5aa Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 15 Jan 2020 17:58:29 +0000 Subject: [PATCH 0047/1537] drm/i915/execlists: Leave resetting ring to intel_ring We need to allow concurrent intel_context_unpin, which means avoiding doing destructive operations like intel_ring_reset(). This was already fixed for intel_ring_unpin() in commit 0725d9a31869 ("drm/i915/gt: Make intel_ring_unpin() safe for concurrent pint"), but I overlooked that execlists_context_unpin() also made the same mistake. Reported-by: Matthew Brost Fixes: 841350223816 ("drm/i915/gt: Drop mutex serialisation between context pin/unpin") References: 0725d9a31869 ("drm/i915/gt: Make intel_ring_unpin() safe for concurrent pint") Signed-off-by: Chris Wilson Cc: Matthew Brost Cc: Matthew Auld Cc: Tvrtko Ursulin Reviewed-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20200115175829.2761329-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_lrc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index a8fe2f16c910..999fe82190da 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -2532,7 +2532,6 @@ static void execlists_context_unpin(struct intel_context *ce) ce->engine); i915_gem_object_unpin_map(ce->state->obj); - intel_ring_reset(ce->ring, ce->ring->tail); } static void From 5e791166d377c539db0f889e7793204912c374da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 10 Jan 2020 16:09:54 +0100 Subject: [PATCH 0048/1537] drm/ttm: nuke invalidate_caches callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Another completely unused feature. Signed-off-by: Christian König Reviewed-by: Huang Rui Link: https://patchwork.freedesktop.org/patch/348265/ --- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 6 ------ drivers/gpu/drm/nouveau/nouveau_bo.c | 8 -------- drivers/gpu/drm/qxl/qxl_ttm.c | 6 ------ drivers/gpu/drm/radeon/radeon_ttm.c | 6 ------ drivers/gpu/drm/ttm/ttm_bo.c | 9 +-------- drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | 6 ------ include/drm/ttm/ttm_bo_driver.h | 15 --------------- 7 files changed, 1 insertion(+), 55 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 445de594c214..7c4b1cbd9a50 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -68,11 +68,6 @@ static int amdgpu_map_buffer(struct ttm_buffer_object *bo, static int amdgpu_ttm_debugfs_init(struct amdgpu_device *adev); static void amdgpu_ttm_debugfs_fini(struct amdgpu_device *adev); -static int amdgpu_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags) -{ - return 0; -} - /** * amdgpu_init_mem_type - Initialize a memory manager for a specific type of * memory request. @@ -1637,7 +1632,6 @@ static struct ttm_bo_driver amdgpu_bo_driver = { .ttm_tt_create = &amdgpu_ttm_tt_create, .ttm_tt_populate = &amdgpu_ttm_tt_populate, .ttm_tt_unpopulate = &amdgpu_ttm_tt_unpopulate, - .invalidate_caches = &amdgpu_invalidate_caches, .init_mem_type = &amdgpu_init_mem_type, .eviction_valuable = amdgpu_ttm_bo_eviction_valuable, .evict_flags = &amdgpu_evict_flags, diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index f8015e0318d7..81668104595f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -646,13 +646,6 @@ nouveau_ttm_tt_create(struct ttm_buffer_object *bo, uint32_t page_flags) return nouveau_sgdma_create_ttm(bo, page_flags); } -static int -nouveau_bo_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags) -{ - /* We'll do this from user space. */ - return 0; -} - static int nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, struct ttm_mem_type_manager *man) @@ -1696,7 +1689,6 @@ struct ttm_bo_driver nouveau_bo_driver = { .ttm_tt_create = &nouveau_ttm_tt_create, .ttm_tt_populate = &nouveau_ttm_tt_populate, .ttm_tt_unpopulate = &nouveau_ttm_tt_unpopulate, - .invalidate_caches = nouveau_bo_invalidate_caches, .init_mem_type = nouveau_bo_init_mem_type, .eviction_valuable = ttm_bo_eviction_valuable, .evict_flags = nouveau_bo_evict_flags, diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c index 16a5e903533d..62a5e424971b 100644 --- a/drivers/gpu/drm/qxl/qxl_ttm.c +++ b/drivers/gpu/drm/qxl/qxl_ttm.c @@ -48,11 +48,6 @@ static struct qxl_device *qxl_get_qdev(struct ttm_bo_device *bdev) return qdev; } -static int qxl_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags) -{ - return 0; -} - static int qxl_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, struct ttm_mem_type_manager *man) { @@ -256,7 +251,6 @@ static void qxl_bo_move_notify(struct ttm_buffer_object *bo, static struct ttm_bo_driver qxl_bo_driver = { .ttm_tt_create = &qxl_ttm_tt_create, - .invalidate_caches = &qxl_invalidate_caches, .init_mem_type = &qxl_init_mem_type, .eviction_valuable = ttm_bo_eviction_valuable, .evict_flags = &qxl_evict_flags, diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index f4af67035673..40282bf0adbe 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -66,11 +66,6 @@ static struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev) return rdev; } -static int radeon_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags) -{ - return 0; -} - static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, struct ttm_mem_type_manager *man) { @@ -774,7 +769,6 @@ static struct ttm_bo_driver radeon_bo_driver = { .ttm_tt_create = &radeon_ttm_tt_create, .ttm_tt_populate = &radeon_ttm_tt_populate, .ttm_tt_unpopulate = &radeon_ttm_tt_unpopulate, - .invalidate_caches = &radeon_invalidate_caches, .init_mem_type = &radeon_init_mem_type, .eviction_valuable = ttm_bo_eviction_valuable, .evict_flags = &radeon_evict_flags, diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 5df596fb0280..06f6d650827f 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -372,14 +372,7 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, } moved: - if (bo->evicted) { - if (bdev->driver->invalidate_caches) { - ret = bdev->driver->invalidate_caches(bdev, bo->mem.placement); - if (ret) - pr_err("Can not flush read caches\n"); - } - bo->evicted = false; - } + bo->evicted = false; if (bo->mem.mm_node) bo->offset = (bo->mem.start << PAGE_SHIFT) + diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c index d8ea3dd10af0..3f3b2c7a208a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c @@ -736,11 +736,6 @@ static struct ttm_tt *vmw_ttm_tt_create(struct ttm_buffer_object *bo, return NULL; } -static int vmw_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags) -{ - return 0; -} - static int vmw_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, struct ttm_mem_type_manager *man) { @@ -866,7 +861,6 @@ struct ttm_bo_driver vmw_bo_driver = { .ttm_tt_create = &vmw_ttm_tt_create, .ttm_tt_populate = &vmw_ttm_populate, .ttm_tt_unpopulate = &vmw_ttm_unpopulate, - .invalidate_caches = vmw_invalidate_caches, .init_mem_type = vmw_init_mem_type, .eviction_valuable = ttm_bo_eviction_valuable, .evict_flags = vmw_evict_flags, diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index cac7a8a0825a..c9e0fd09f4b2 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -210,8 +210,6 @@ struct ttm_mem_type_manager { * struct ttm_bo_driver * * @create_ttm_backend_entry: Callback to create a struct ttm_backend. - * @invalidate_caches: Callback to invalidate read caches when a buffer object - * has been evicted. * @init_mem_type: Callback to initialize a struct ttm_mem_type_manager * structure. * @evict_flags: Callback to obtain placement flags when a buffer is evicted. @@ -256,19 +254,6 @@ struct ttm_bo_driver { */ void (*ttm_tt_unpopulate)(struct ttm_tt *ttm); - /** - * struct ttm_bo_driver member invalidate_caches - * - * @bdev: the buffer object device. - * @flags: new placement of the rebound buffer object. - * - * A previosly evicted buffer has been rebound in a - * potentially new location. Tell the driver that it might - * consider invalidating read (texture) caches on the next command - * submission as a consequence. - */ - - int (*invalidate_caches)(struct ttm_bo_device *bdev, uint32_t flags); int (*init_mem_type)(struct ttm_bo_device *bdev, uint32_t type, struct ttm_mem_type_manager *man); From 9c92aa483a3c0b70c5a6d6deeb7c539696c90cec Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 16 Jan 2020 12:57:49 +0000 Subject: [PATCH 0049/1537] drm/i915/gt: Drop rogue space in the middle of GT_TRACE Remove the double space that crept into the fmt stringification. Signed-off-by: Chris Wilson Reviewed-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20200116125749.2786743-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_gt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h b/drivers/gpu/drm/i915/gt/intel_gt.h index 1dac441cb8f4..4fac043750aa 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt.h +++ b/drivers/gpu/drm/i915/gt/intel_gt.h @@ -14,7 +14,7 @@ struct drm_i915_private; #define GT_TRACE(gt, fmt, ...) do { \ const struct intel_gt *gt__ __maybe_unused = (gt); \ - GEM_TRACE("%s " fmt, dev_name(gt__->i915->drm.dev), \ + GEM_TRACE("%s " fmt, dev_name(gt__->i915->drm.dev), \ ##__VA_ARGS__); \ } while (0) From 6f4194c8771f5182017be011e0a0fc1c053b18eb Mon Sep 17 00:00:00 2001 From: Matt Atwood Date: Mon, 13 Jan 2020 23:11:28 -0500 Subject: [PATCH 0050/1537] drm/i915: add Wa_14010594013: icl,ehl The bspec tells us we need to set this bit to avoid potential underruns. v2: use new register write convention (Anshuman) add bspec 7386 ref. Bspec: 7386 Bspec: 33450 Bspec: 33451 Cc: Anshuman Gupta Reviewed-by: Rodrigo Vivi Signed-off-by: Matt Atwood Reviewed-by: Anshuman Gupta Signed-off-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20200114041128.11211-1-matthew.s.atwood@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_pm.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5e5949edf2a8..b93c4c18f05c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7769,6 +7769,7 @@ enum { #define GEN8_CHICKEN_DCPR_1 _MMIO(0x46430) #define SKL_SELECT_ALTERNATE_DC_EXIT (1 << 30) +#define CNL_DELAY_PMRSP (1 << 22) #define MASK_WAKEMEM (1 << 13) #define CNL_DDI_CLOCK_REG_ACCESS_ON (1 << 7) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 8e5f08c58b0c..81e5a3278fda 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6643,6 +6643,10 @@ static void icl_init_clock_gating(struct drm_i915_private *dev_priv) /* Wa_1407352427:icl,ehl */ intel_uncore_rmw(&dev_priv->uncore, UNSLICE_UNIT_LEVEL_CLKGATE2, 0, PSDUNIT_CLKGATE_DIS); + + /*Wa_14010594013:icl, ehl */ + intel_uncore_rmw(&dev_priv->uncore, GEN8_CHICKEN_DCPR_1, + 0, CNL_DELAY_PMRSP); } static void tgl_init_clock_gating(struct drm_i915_private *dev_priv) From 9e83713a721b185774e32879b85f0b2ea615936b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Roberto=20de=20Souza?= Date: Mon, 13 Jan 2020 13:46:03 -0800 Subject: [PATCH 0051/1537] drm/i915/psr: Share the computation of idle frames MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both activate functions and the dc3co disable function were doing the same thing, so better move to a function and share. Also while at it adding a WARN_ON to catch invalid values. Cc: Anshuman Gupta Cc: Imre Deak Reviewed-by: Anshuman Gupta Signed-off-by: José Roberto de Souza Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20200113214603.52158-1-jose.souza@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 46 +++++++++++------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 89c9cf5f38d2..1d2fd1a8925a 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -454,22 +454,30 @@ static u32 intel_psr1_get_tp_time(struct intel_dp *intel_dp) return val; } +static u8 psr_compute_idle_frames(struct intel_dp *intel_dp) +{ + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + int idle_frames; + + /* Let's use 6 as the minimum to cover all known cases including the + * off-by-one issue that HW has in some cases. + */ + idle_frames = max(6, dev_priv->vbt.psr.idle_frames); + idle_frames = max(idle_frames, dev_priv->psr.sink_sync_latency + 1); + + if (WARN_ON(idle_frames > 0xf)) + idle_frames = 0xf; + + return idle_frames; +} + static void hsw_activate_psr1(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); u32 max_sleep_time = 0x1f; u32 val = EDP_PSR_ENABLE; - /* Let's use 6 as the minimum to cover all known cases including the - * off-by-one issue that HW has in some cases. - */ - int idle_frames = max(6, dev_priv->vbt.psr.idle_frames); - - /* sink_sync_latency of 8 means source has to wait for more than 8 - * frames, we'll go with 9 frames for now - */ - idle_frames = max(idle_frames, dev_priv->psr.sink_sync_latency + 1); - val |= idle_frames << EDP_PSR_IDLE_FRAME_SHIFT; + val |= psr_compute_idle_frames(intel_dp) << EDP_PSR_IDLE_FRAME_SHIFT; val |= max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT; if (IS_HASWELL(dev_priv)) @@ -493,13 +501,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp) struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); u32 val; - /* Let's use 6 as the minimum to cover all known cases including the - * off-by-one issue that HW has in some cases. - */ - int idle_frames = max(6, dev_priv->vbt.psr.idle_frames); - - idle_frames = max(idle_frames, dev_priv->psr.sink_sync_latency + 1); - val = idle_frames << EDP_PSR2_IDLE_FRAME_SHIFT; + val = psr_compute_idle_frames(intel_dp) << EDP_PSR2_IDLE_FRAME_SHIFT; val |= EDP_PSR2_ENABLE | EDP_SU_TRACK_ENABLE; if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) @@ -566,16 +568,10 @@ static void tgl_psr2_enable_dc3co(struct drm_i915_private *dev_priv) static void tgl_psr2_disable_dc3co(struct drm_i915_private *dev_priv) { - int idle_frames; + struct intel_dp *intel_dp = dev_priv->psr.dp; intel_display_power_set_target_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6); - /* - * Restore PSR2 idle frame let's use 6 as the minimum to cover all known - * cases including the off-by-one issue that HW has in some cases. - */ - idle_frames = max(6, dev_priv->vbt.psr.idle_frames); - idle_frames = max(idle_frames, dev_priv->psr.sink_sync_latency + 1); - psr2_program_idle_frames(dev_priv, idle_frames); + psr2_program_idle_frames(dev_priv, psr_compute_idle_frames(intel_dp)); } static void tgl_dc5_idle_thread(struct work_struct *work) From 672c368f9398042b629740cc9816e8e939eff2db Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 16 Jan 2020 18:47:52 +0000 Subject: [PATCH 0052/1537] drm/i915: Keep track of request among the scheduling lists If we keep track of when the i915_request.sched.link is on the HW runlist, or in the priority queue we can simplify our interactions with the request (such as during rescheduling). This also simplifies the next patch where we introduce a new in-between list, for requests that are ready but neither on the run list or in the queue. v2: Update i915_sched_node.link explanation for current usage where it is a link on both the queue and on the runlists. Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20200116184754.2860848-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_lrc.c | 13 ++++++++----- drivers/gpu/drm/i915/i915_request.c | 4 +++- drivers/gpu/drm/i915/i915_request.h | 17 +++++++++++++++++ drivers/gpu/drm/i915/i915_scheduler.c | 22 ++++++++++------------ 4 files changed, 38 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index 999fe82190da..4cd88019fc2d 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -985,6 +985,8 @@ __unwind_incomplete_requests(struct intel_engine_cs *engine) GEM_BUG_ON(RB_EMPTY_ROOT(&engine->execlists.queue.rb_root)); list_move(&rq->sched.link, pl); + set_bit(I915_FENCE_FLAG_PQUEUE, &rq->fence.flags); + active = rq; } else { struct intel_engine_cs *owner = rq->context->engine; @@ -2431,11 +2433,12 @@ static void execlists_preempt(struct timer_list *timer) } static void queue_request(struct intel_engine_cs *engine, - struct i915_sched_node *node, - int prio) + struct i915_request *rq) { - GEM_BUG_ON(!list_empty(&node->link)); - list_add_tail(&node->link, i915_sched_lookup_priolist(engine, prio)); + GEM_BUG_ON(!list_empty(&rq->sched.link)); + list_add_tail(&rq->sched.link, + i915_sched_lookup_priolist(engine, rq_prio(rq))); + set_bit(I915_FENCE_FLAG_PQUEUE, &rq->fence.flags); } static void __submit_queue_imm(struct intel_engine_cs *engine) @@ -2471,7 +2474,7 @@ static void execlists_submit_request(struct i915_request *request) /* Will be called from irq-context when using foreign fences. */ spin_lock_irqsave(&engine->active.lock, flags); - queue_request(engine, &request->sched, rq_prio(request)); + queue_request(engine, request); GEM_BUG_ON(RB_EMPTY_ROOT(&engine->execlists.queue.rb_root)); GEM_BUG_ON(list_empty(&request->sched.link)); diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index be185886e4fc..9ed0d3bc7249 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -408,8 +408,10 @@ bool __i915_request_submit(struct i915_request *request) xfer: /* We may be recursing from the signal callback of another i915 fence */ spin_lock_nested(&request->lock, SINGLE_DEPTH_NESTING); - if (!test_and_set_bit(I915_FENCE_FLAG_ACTIVE, &request->fence.flags)) + if (!test_and_set_bit(I915_FENCE_FLAG_ACTIVE, &request->fence.flags)) { list_move_tail(&request->sched.link, &engine->active.requests); + clear_bit(I915_FENCE_FLAG_PQUEUE, &request->fence.flags); + } if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &request->fence.flags) && !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &request->fence.flags) && diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h index 031433691a06..6f5bbfa95513 100644 --- a/drivers/gpu/drm/i915/i915_request.h +++ b/drivers/gpu/drm/i915/i915_request.h @@ -70,6 +70,18 @@ enum { */ I915_FENCE_FLAG_ACTIVE = DMA_FENCE_FLAG_USER_BITS, + /* + * I915_FENCE_FLAG_PQUEUE - this request is ready for execution + * + * Using the scheduler, when a request is ready for execution it is put + * into the priority queue, and removed from that queue when transferred + * to the HW runlists. We want to track its membership within the + * priority queue so that we can easily check before rescheduling. + * + * See i915_request_in_priority_queue() + */ + I915_FENCE_FLAG_PQUEUE, + /* * I915_FENCE_FLAG_SIGNAL - this request is currently on signal_list * @@ -361,6 +373,11 @@ static inline bool i915_request_is_active(const struct i915_request *rq) return test_bit(I915_FENCE_FLAG_ACTIVE, &rq->fence.flags); } +static inline bool i915_request_in_priority_queue(const struct i915_request *rq) +{ + return test_bit(I915_FENCE_FLAG_PQUEUE, &rq->fence.flags); +} + /** * Returns true if seq1 is later than seq2. */ diff --git a/drivers/gpu/drm/i915/i915_scheduler.c b/drivers/gpu/drm/i915/i915_scheduler.c index bf87c70bfdd9..5d96cfba40f8 100644 --- a/drivers/gpu/drm/i915/i915_scheduler.c +++ b/drivers/gpu/drm/i915/i915_scheduler.c @@ -326,20 +326,18 @@ static void __i915_schedule(struct i915_sched_node *node, node->attr.priority = prio; - if (list_empty(&node->link)) { - /* - * If the request is not in the priolist queue because - * it is not yet runnable, then it doesn't contribute - * to our preemption decisions. On the other hand, - * if the request is on the HW, it too is not in the - * queue; but in that case we may still need to reorder - * the inflight requests. - */ + /* + * Once the request is ready, it will be placed into the + * priority lists and then onto the HW runlist. Before the + * request is ready, it does not contribute to our preemption + * decisions and we can safely ignore it, as it will, and + * any preemption required, be dealt with upon submission. + * See engine->submit_request() + */ + if (list_empty(&node->link)) continue; - } - if (!intel_engine_is_virtual(engine) && - !i915_request_is_active(node_to_request(node))) { + if (i915_request_in_priority_queue(node_to_request(node))) { if (!cache.priolist) cache.priolist = i915_sched_lookup_priolist(engine, From 32ff621fd74496f0c33644125fb69ff175859b1f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 16 Jan 2020 18:47:53 +0000 Subject: [PATCH 0053/1537] drm/i915/gt: Allow temporary suspension of inflight requests In order to support out-of-line error capture, we need to remove the active request from HW and put it to one side while a worker compresses and stores all the details associated with that request. (As that compression may take an arbitrary user-controlled amount of time, we want to let the engine continue running on other workloads while the hanging request is dumped.) Not only do we need to remove the active request, but we also have to remove its context and all requests that were dependent on it (both in flight, queued and future submission). Finally once the capture is complete, we need to be able to resubmit the request and its dependents and allow them to execute. v2: Replace stack recursion with a simple list. v3: Check all the parents, not just the first, when searching for a stuck ancestor! References: https://gitlab.freedesktop.org/drm/intel/issues/738 Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20200116184754.2860848-2-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 13 ++ drivers/gpu/drm/i915/gt/intel_engine_types.h | 1 + drivers/gpu/drm/i915/gt/intel_lrc.c | 167 ++++++++++++++++++- drivers/gpu/drm/i915/gt/selftest_lrc.c | 103 ++++++++++++ drivers/gpu/drm/i915/i915_request.h | 43 +++++ 5 files changed, 321 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index f451ef376548..06ff7695fa29 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -671,6 +671,7 @@ void intel_engine_init_active(struct intel_engine_cs *engine, unsigned int subclass) { INIT_LIST_HEAD(&engine->active.requests); + INIT_LIST_HEAD(&engine->active.hold); spin_lock_init(&engine->active.lock); lockdep_set_subclass(&engine->active.lock, subclass); @@ -1422,6 +1423,17 @@ static void print_request_ring(struct drm_printer *m, struct i915_request *rq) } } +static unsigned long list_count(struct list_head *list) +{ + struct list_head *pos; + unsigned long count = 0; + + list_for_each(pos, list) + count++; + + return count; +} + void intel_engine_dump(struct intel_engine_cs *engine, struct drm_printer *m, const char *header, ...) @@ -1491,6 +1503,7 @@ void intel_engine_dump(struct intel_engine_cs *engine, hexdump(m, rq->context->lrc_reg_state, PAGE_SIZE); } } + drm_printf(m, "\tOn hold?: %lu\n", list_count(&engine->active.hold)); spin_unlock_irqrestore(&engine->active.lock, flags); drm_printf(m, "\tMMIO base: 0x%08x\n", engine->mmio_base); diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h index 00287515e7af..77e68c7643de 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h @@ -295,6 +295,7 @@ struct intel_engine_cs { struct { spinlock_t lock; struct list_head requests; + struct list_head hold; /* ready requests, but on hold */ } active; struct llist_head barrier_tasks; diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index 4cd88019fc2d..43375c44c85a 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -1635,8 +1635,8 @@ static void defer_request(struct i915_request *rq, struct list_head * const pl) !i915_request_completed(rq)); GEM_BUG_ON(i915_request_is_active(w)); - if (list_empty(&w->sched.link)) - continue; /* Not yet submitted; unready */ + if (!i915_request_is_ready(w)) + continue; if (rq_prio(w) < rq_prio(rq)) continue; @@ -2354,6 +2354,145 @@ static void __execlists_submission_tasklet(struct intel_engine_cs *const engine) } } +static void __execlists_hold(struct i915_request *rq) +{ + LIST_HEAD(list); + + do { + struct i915_dependency *p; + + if (i915_request_is_active(rq)) + __i915_request_unsubmit(rq); + + RQ_TRACE(rq, "on hold\n"); + clear_bit(I915_FENCE_FLAG_PQUEUE, &rq->fence.flags); + list_move_tail(&rq->sched.link, &rq->engine->active.hold); + i915_request_set_hold(rq); + + list_for_each_entry(p, &rq->sched.waiters_list, wait_link) { + struct i915_request *w = + container_of(p->waiter, typeof(*w), sched); + + /* Leave semaphores spinning on the other engines */ + if (w->engine != rq->engine) + continue; + + if (!i915_request_is_ready(w)) + continue; + + if (i915_request_completed(w)) + continue; + + if (i915_request_on_hold(rq)) + continue; + + list_move_tail(&w->sched.link, &list); + } + + rq = list_first_entry_or_null(&list, typeof(*rq), sched.link); + } while (rq); +} + +__maybe_unused +static void execlists_hold(struct intel_engine_cs *engine, + struct i915_request *rq) +{ + spin_lock_irq(&engine->active.lock); + + /* + * Transfer this request onto the hold queue to prevent it + * being resumbitted to HW (and potentially completed) before we have + * released it. Since we may have already submitted following + * requests, we need to remove those as well. + */ + GEM_BUG_ON(i915_request_on_hold(rq)); + GEM_BUG_ON(rq->engine != engine); + __execlists_hold(rq); + + spin_unlock_irq(&engine->active.lock); +} + +static bool hold_request(const struct i915_request *rq) +{ + struct i915_dependency *p; + + /* + * If one of our ancestors is on hold, we must also be on hold, + * otherwise we will bypass it and execute before it. + */ + list_for_each_entry(p, &rq->sched.signalers_list, signal_link) { + const struct i915_request *s = + container_of(p->signaler, typeof(*s), sched); + + if (s->engine != rq->engine) + continue; + + if (i915_request_on_hold(s)) + return true; + } + + return false; +} + +static void __execlists_unhold(struct i915_request *rq) +{ + LIST_HEAD(list); + + do { + struct i915_dependency *p; + + GEM_BUG_ON(!i915_request_on_hold(rq)); + GEM_BUG_ON(!i915_sw_fence_signaled(&rq->submit)); + + i915_request_clear_hold(rq); + list_move_tail(&rq->sched.link, + i915_sched_lookup_priolist(rq->engine, + rq_prio(rq))); + set_bit(I915_FENCE_FLAG_PQUEUE, &rq->fence.flags); + RQ_TRACE(rq, "hold release\n"); + + /* Also release any children on this engine that are ready */ + list_for_each_entry(p, &rq->sched.waiters_list, wait_link) { + struct i915_request *w = + container_of(p->waiter, typeof(*w), sched); + + if (w->engine != rq->engine) + continue; + + if (!i915_request_on_hold(rq)) + continue; + + /* Check that no other parents are also on hold */ + if (hold_request(rq)) + continue; + + list_move_tail(&w->sched.link, &list); + } + + rq = list_first_entry_or_null(&list, typeof(*rq), sched.link); + } while (rq); +} + +__maybe_unused +static void execlists_unhold(struct intel_engine_cs *engine, + struct i915_request *rq) +{ + spin_lock_irq(&engine->active.lock); + + /* + * Move this request back to the priority queue, and all of its + * children and grandchildren that were suspended along with it. + */ + __execlists_unhold(rq); + + if (rq_prio(rq) > engine->execlists.queue_priority_hint) { + engine->execlists.queue_priority_hint = rq_prio(rq); + tasklet_hi_schedule(&engine->execlists.tasklet); + } + + spin_unlock_irq(&engine->active.lock); +} + static noinline void preempt_reset(struct intel_engine_cs *engine) { const unsigned int bit = I915_RESET_ENGINE + engine->id; @@ -2466,6 +2605,13 @@ static void submit_queue(struct intel_engine_cs *engine, __submit_queue_imm(engine); } +static bool ancestor_on_hold(const struct intel_engine_cs *engine, + const struct i915_request *rq) +{ + GEM_BUG_ON(i915_request_on_hold(rq)); + return !list_empty(&engine->active.hold) && hold_request(rq); +} + static void execlists_submit_request(struct i915_request *request) { struct intel_engine_cs *engine = request->engine; @@ -2474,12 +2620,17 @@ static void execlists_submit_request(struct i915_request *request) /* Will be called from irq-context when using foreign fences. */ spin_lock_irqsave(&engine->active.lock, flags); - queue_request(engine, request); + if (unlikely(ancestor_on_hold(engine, request))) { + list_add_tail(&request->sched.link, &engine->active.hold); + i915_request_set_hold(request); + } else { + queue_request(engine, request); - GEM_BUG_ON(RB_EMPTY_ROOT(&engine->execlists.queue.rb_root)); - GEM_BUG_ON(list_empty(&request->sched.link)); + GEM_BUG_ON(RB_EMPTY_ROOT(&engine->execlists.queue.rb_root)); + GEM_BUG_ON(list_empty(&request->sched.link)); - submit_queue(engine, request); + submit_queue(engine, request); + } spin_unlock_irqrestore(&engine->active.lock, flags); } @@ -3320,6 +3471,10 @@ static void execlists_reset_cancel(struct intel_engine_cs *engine) i915_priolist_free(p); } + /* On-hold requests will be flushed to timeline upon their release */ + list_for_each_entry(rq, &engine->active.hold, sched.link) + mark_eio(rq); + /* Cancel all attached virtual engines */ while ((rb = rb_first_cached(&execlists->virtual))) { struct virtual_engine *ve = diff --git a/drivers/gpu/drm/i915/gt/selftest_lrc.c b/drivers/gpu/drm/i915/gt/selftest_lrc.c index 15cda024e3e4..b208c2176bbd 100644 --- a/drivers/gpu/drm/i915/gt/selftest_lrc.c +++ b/drivers/gpu/drm/i915/gt/selftest_lrc.c @@ -285,6 +285,108 @@ static int live_unlite_preempt(void *arg) return live_unlite_restore(arg, I915_USER_PRIORITY(I915_PRIORITY_MAX)); } +static int live_hold_reset(void *arg) +{ + struct intel_gt *gt = arg; + struct intel_engine_cs *engine; + enum intel_engine_id id; + struct igt_spinner spin; + int err = 0; + + /* + * In order to support offline error capture for fast preempt reset, + * we need to decouple the guilty request and ensure that it and its + * descendents are not executed while the capture is in progress. + */ + + if (!intel_has_reset_engine(gt)) + return 0; + + if (igt_spinner_init(&spin, gt)) + return -ENOMEM; + + for_each_engine(engine, gt, id) { + struct intel_context *ce; + unsigned long heartbeat; + struct i915_request *rq; + + ce = intel_context_create(engine); + if (IS_ERR(ce)) { + err = PTR_ERR(ce); + break; + } + + engine_heartbeat_disable(engine, &heartbeat); + + rq = igt_spinner_create_request(&spin, ce, MI_ARB_CHECK); + if (IS_ERR(rq)) { + err = PTR_ERR(rq); + goto out; + } + i915_request_add(rq); + + if (!igt_wait_for_spinner(&spin, rq)) { + intel_gt_set_wedged(gt); + err = -ETIME; + goto out; + } + + /* We have our request executing, now remove it and reset */ + + if (test_and_set_bit(I915_RESET_ENGINE + id, + >->reset.flags)) { + spin_unlock_irq(&engine->active.lock); + intel_gt_set_wedged(gt); + err = -EBUSY; + goto out; + } + tasklet_disable(&engine->execlists.tasklet); + + engine->execlists.tasklet.func(engine->execlists.tasklet.data); + GEM_BUG_ON(execlists_active(&engine->execlists) != rq); + + execlists_hold(engine, rq); + GEM_BUG_ON(!i915_request_on_hold(rq)); + + intel_engine_reset(engine, NULL); + GEM_BUG_ON(rq->fence.error != -EIO); + + tasklet_enable(&engine->execlists.tasklet); + clear_and_wake_up_bit(I915_RESET_ENGINE + id, + >->reset.flags); + + /* Check that we do not resubmit the held request */ + i915_request_get(rq); + if (!i915_request_wait(rq, 0, HZ / 5)) { + pr_err("%s: on hold request completed!\n", + engine->name); + i915_request_put(rq); + err = -EIO; + goto out; + } + GEM_BUG_ON(!i915_request_on_hold(rq)); + + /* But is resubmitted on release */ + execlists_unhold(engine, rq); + if (i915_request_wait(rq, 0, HZ / 5) < 0) { + pr_err("%s: held request did not complete!\n", + engine->name); + intel_gt_set_wedged(gt); + err = -ETIME; + } + i915_request_put(rq); + +out: + engine_heartbeat_enable(engine, heartbeat); + intel_context_put(ce); + if (err) + break; + } + + igt_spinner_fini(&spin); + return err; +} + static int emit_semaphore_chain(struct i915_request *rq, struct i915_vma *vma, int idx) { @@ -3315,6 +3417,7 @@ int intel_execlists_live_selftests(struct drm_i915_private *i915) SUBTEST(live_sanitycheck), SUBTEST(live_unlite_switch), SUBTEST(live_unlite_preempt), + SUBTEST(live_hold_reset), SUBTEST(live_timeslice_preempt), SUBTEST(live_timeslice_queue), SUBTEST(live_busywait_preempt), diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h index 6f5bbfa95513..f57eadcf3583 100644 --- a/drivers/gpu/drm/i915/i915_request.h +++ b/drivers/gpu/drm/i915/i915_request.h @@ -90,6 +90,13 @@ enum { */ I915_FENCE_FLAG_SIGNAL, + /* + * I915_FENCE_FLAG_HOLD - this request is currently on hold + * + * This request has been suspended, pending an ongoing investigation. + */ + I915_FENCE_FLAG_HOLD, + /* * I915_FENCE_FLAG_NOPREEMPT - this request should not be preempted * @@ -471,6 +478,27 @@ static inline bool i915_request_is_running(const struct i915_request *rq) return __i915_request_has_started(rq); } +/** + * i915_request_is_running - check if the request is ready for execution + * @rq: the request + * + * Upon construction, the request is instructed to wait upon various + * signals before it is ready to be executed by the HW. That is, we do + * not want to start execution and read data before it is written. In practice, + * this is controlled with a mixture of interrupts and semaphores. Once + * the submit fence is completed, the backend scheduler will place the + * request into its queue and from there submit it for execution. So we + * can detect when a request is eligible for execution (and is under control + * of the scheduler) by querying where it is in any of the scheduler's lists. + * + * Returns true if the request is ready for execution (it may be inflight), + * false otherwise. + */ +static inline bool i915_request_is_ready(const struct i915_request *rq) +{ + return !list_empty(&rq->sched.link); +} + static inline bool i915_request_completed(const struct i915_request *rq) { if (i915_request_signaled(rq)) @@ -500,6 +528,21 @@ static inline bool i915_request_has_sentinel(const struct i915_request *rq) return unlikely(test_bit(I915_FENCE_FLAG_SENTINEL, &rq->fence.flags)); } +static inline bool i915_request_on_hold(const struct i915_request *rq) +{ + return unlikely(test_bit(I915_FENCE_FLAG_HOLD, &rq->fence.flags)); +} + +static inline void i915_request_set_hold(struct i915_request *rq) +{ + set_bit(I915_FENCE_FLAG_HOLD, &rq->fence.flags); +} + +static inline void i915_request_clear_hold(struct i915_request *rq) +{ + clear_bit(I915_FENCE_FLAG_HOLD, &rq->fence.flags); +} + static inline struct intel_timeline * i915_request_timeline(struct i915_request *rq) { From 748317386afb235e11616098d2c7772e49776b58 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 16 Jan 2020 18:47:54 +0000 Subject: [PATCH 0054/1537] drm/i915/execlists: Offline error capture Currently, we skip error capture upon forced preemption. We apply forced preemption when there is a higher priority request that should be running but is being blocked, and we skip inline error capture so that the preemption request is not further delayed by a user controlled capture -- extending the denial of service. However, preemption reset is also used for heartbeats and regular GPU hangs. By skipping the error capture, we remove the ability to debug GPU hangs. In order to capture the error without delaying the preemption request further, we can do an out-of-line capture by removing the guilty request from the execution queue and scheduling a worker to dump that request. When removing a request, we need to remove the entire context and all descendants from the execution queue, so that they do not jump past. Closes: https://gitlab.freedesktop.org/drm/intel/issues/738 Fixes: 3a7a92aba8fb ("drm/i915/execlists: Force preemption") Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20200116184754.2860848-3-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_lrc.c | 122 +++++++++++++++++++++++++++- 1 file changed, 120 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index 43375c44c85a..2d6b41e66b16 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -2393,7 +2393,6 @@ static void __execlists_hold(struct i915_request *rq) } while (rq); } -__maybe_unused static void execlists_hold(struct intel_engine_cs *engine, struct i915_request *rq) { @@ -2473,7 +2472,6 @@ static void __execlists_unhold(struct i915_request *rq) } while (rq); } -__maybe_unused static void execlists_unhold(struct intel_engine_cs *engine, struct i915_request *rq) { @@ -2493,6 +2491,123 @@ static void execlists_unhold(struct intel_engine_cs *engine, spin_unlock_irq(&engine->active.lock); } +struct execlists_capture { + struct work_struct work; + struct i915_request *rq; + struct i915_gpu_coredump *error; +}; + +static void execlists_capture_work(struct work_struct *work) +{ + struct execlists_capture *cap = container_of(work, typeof(*cap), work); + const gfp_t gfp = GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN; + struct intel_engine_cs *engine = cap->rq->engine; + struct intel_gt_coredump *gt = cap->error->gt; + struct intel_engine_capture_vma *vma; + + /* Compress all the objects attached to the request, slow! */ + vma = intel_engine_coredump_add_request(gt->engine, cap->rq, gfp); + if (vma) { + struct i915_vma_compress *compress = + i915_vma_capture_prepare(gt); + + intel_engine_coredump_add_vma(gt->engine, vma, compress); + i915_vma_capture_finish(gt, compress); + } + + gt->simulated = gt->engine->simulated; + cap->error->simulated = gt->simulated; + + /* Publish the error state, and announce it to the world */ + i915_error_state_store(cap->error); + i915_gpu_coredump_put(cap->error); + + /* Return this request and all that depend upon it for signaling */ + execlists_unhold(engine, cap->rq); + + kfree(cap); +} + +static struct execlists_capture *capture_regs(struct intel_engine_cs *engine) +{ + const gfp_t gfp = GFP_ATOMIC | __GFP_NOWARN; + struct execlists_capture *cap; + + cap = kmalloc(sizeof(*cap), gfp); + if (!cap) + return NULL; + + cap->error = i915_gpu_coredump_alloc(engine->i915, gfp); + if (!cap->error) + goto err_cap; + + cap->error->gt = intel_gt_coredump_alloc(engine->gt, gfp); + if (!cap->error->gt) + goto err_gpu; + + cap->error->gt->engine = intel_engine_coredump_alloc(engine, gfp); + if (!cap->error->gt->engine) + goto err_gt; + + return cap; + +err_gt: + kfree(cap->error->gt); +err_gpu: + kfree(cap->error); +err_cap: + kfree(cap); + return NULL; +} + +static void execlists_capture(struct intel_engine_cs *engine) +{ + struct execlists_capture *cap; + + if (!IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)) + return; + + /* + * We need to _quickly_ capture the engine state before we reset. + * We are inside an atomic section (softirq) here and we are delaying + * the forced preemption event. + */ + cap = capture_regs(engine); + if (!cap) + return; + + cap->rq = execlists_active(&engine->execlists); + GEM_BUG_ON(!cap->rq); + + cap->rq = active_request(cap->rq->context->timeline, cap->rq); + GEM_BUG_ON(!cap->rq); + + /* + * Remove the request from the execlists queue, and take ownership + * of the request. We pass it to our worker who will _slowly_ compress + * all the pages the _user_ requested for debugging their batch, after + * which we return it to the queue for signaling. + * + * By removing them from the execlists queue, we also remove the + * requests from being processed by __unwind_incomplete_requests() + * during the intel_engine_reset(), and so they will *not* be replayed + * afterwards. + * + * Note that because we have not yet reset the engine at this point, + * it is possible for the request that we have identified as being + * guilty, did in fact complete and we will then hit an arbitration + * point allowing the outstanding preemption to succeed. The likelihood + * of that is very low (as capturing of the engine registers should be + * fast enough to run inside an irq-off atomic section!), so we will + * simply hold that request accountable for being non-preemptible + * long enough to force the reset. + */ + execlists_hold(engine, cap->rq); + + INIT_WORK(&cap->work, execlists_capture_work); + schedule_work(&cap->work); +} + static noinline void preempt_reset(struct intel_engine_cs *engine) { const unsigned int bit = I915_RESET_ENGINE + engine->id; @@ -2510,6 +2625,9 @@ static noinline void preempt_reset(struct intel_engine_cs *engine) ENGINE_TRACE(engine, "preempt timeout %lu+%ums\n", READ_ONCE(engine->props.preempt_timeout_ms), jiffies_to_msecs(jiffies - engine->execlists.preempt.expires)); + + ring_set_paused(engine, 1); /* Freeze the current request in place */ + execlists_capture(engine); intel_engine_reset(engine, "preemption time out"); tasklet_enable(&engine->execlists.tasklet); From 960287ca58fd549af9826ff1cb735fe17d031486 Mon Sep 17 00:00:00 2001 From: Vivek Kasireddy Date: Tue, 14 Jan 2020 17:23:05 -0800 Subject: [PATCH 0055/1537] drm/i915/dsi: Lookup the i2c bus from ACPI NS only if CONFIG_ACPI=y (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Perform the i2c bus/adapter lookup from ACPI Namespace only if ACPI is enabled in the kernel config. If ACPI is not enabled or if the lookup fails, we'll fallback to using the VBT for identifying the i2c bus. v2: Add fixes tag (Jani) Fixes: 8cbf89db2941 ("drm/i915/dsi: Parse the I2C element from the VBT MIPI sequence block (v3)") Cc: Hans de Goede Cc: Nabendu Maiti Cc: Matt Roper Cc: Bob Paauwe Cc: Ville Syrjälä Cc: Jani Nikula Cc: Zhang Xiaoxu Reported-by: Hulk Robot Signed-off-by: Vivek Kasireddy Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20200115012305.27395-1-vivek.kasireddy@intel.com --- drivers/gpu/drm/i915/display/intel_dsi_vbt.c | 49 +++++++++++++------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c index 89fb0d90b694..6ec35d975bd7 100644 --- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c @@ -384,6 +384,7 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) return data; } +#ifdef CONFIG_ACPI static int i2c_adapter_lookup(struct acpi_resource *ares, void *data) { struct i2c_adapter_lookup *lookup = data; @@ -413,14 +414,41 @@ static int i2c_adapter_lookup(struct acpi_resource *ares, void *data) return 1; } +static void i2c_acpi_find_adapter(struct intel_dsi *intel_dsi, + const u16 slave_addr) +{ + struct drm_device *drm_dev = intel_dsi->base.base.dev; + struct device *dev = &drm_dev->pdev->dev; + struct acpi_device *acpi_dev; + struct list_head resource_list; + struct i2c_adapter_lookup lookup; + + acpi_dev = ACPI_COMPANION(dev); + if (acpi_dev) { + memset(&lookup, 0, sizeof(lookup)); + lookup.slave_addr = slave_addr; + lookup.intel_dsi = intel_dsi; + lookup.dev_handle = acpi_device_handle(acpi_dev); + + INIT_LIST_HEAD(&resource_list); + acpi_dev_get_resources(acpi_dev, &resource_list, + i2c_adapter_lookup, + &lookup); + acpi_dev_free_resource_list(&resource_list); + } +} +#else +static inline void i2c_acpi_find_adapter(struct intel_dsi *intel_dsi, + const u16 slave_addr) +{ +} +#endif + static const u8 *mipi_exec_i2c(struct intel_dsi *intel_dsi, const u8 *data) { struct drm_device *drm_dev = intel_dsi->base.base.dev; struct device *dev = &drm_dev->pdev->dev; struct i2c_adapter *adapter; - struct acpi_device *acpi_dev; - struct list_head resource_list; - struct i2c_adapter_lookup lookup; struct i2c_msg msg; int ret; u8 vbt_i2c_bus_num = *(data + 2); @@ -431,20 +459,7 @@ static const u8 *mipi_exec_i2c(struct intel_dsi *intel_dsi, const u8 *data) if (intel_dsi->i2c_bus_num < 0) { intel_dsi->i2c_bus_num = vbt_i2c_bus_num; - - acpi_dev = ACPI_COMPANION(dev); - if (acpi_dev) { - memset(&lookup, 0, sizeof(lookup)); - lookup.slave_addr = slave_addr; - lookup.intel_dsi = intel_dsi; - lookup.dev_handle = acpi_device_handle(acpi_dev); - - INIT_LIST_HEAD(&resource_list); - acpi_dev_get_resources(acpi_dev, &resource_list, - i2c_adapter_lookup, - &lookup); - acpi_dev_free_resource_list(&resource_list); - } + i2c_acpi_find_adapter(intel_dsi, slave_addr); } adapter = i2c_get_adapter(intel_dsi->i2c_bus_num); From fde7266fb2f6fff2a7fe861474bf198ef0f2449f Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Thu, 16 Jan 2020 16:16:08 -0500 Subject: [PATCH 0056/1537] drm/i915: Fix eDP DPCD aux max backlight calculations Max backlight value for the panel was being calculated using byte count i.e. 0xffff if 2 bytes are supported for backlight brightness and 0xff if 1 byte is supported. However, EDP_PWMGEN_BIT_COUNT determines the number of active control bits used for the brightness setting. Thus, even if the panel uses 2 byte setting, it might not use all the control bits. Thus, max backlight should be set based on the value of EDP_PWMGEN_BIT_COUNT instead of assuming 65535 or 255. Additionally, EDP_PWMGEN_BIT_COUNT was being updated based on the VBT frequency which results in a different max backlight value. Thus, setting of EDP_PWMGEN_BIT_COUNT is moved to setup phase instead of enable so that max backlight can be calculated correctly. Only the frequency divider is set during the enable phase using the value of EDP_PWMGEN_BIT_COUNT. This is based off the original patch series from Furquan Shaikh : https://patchwork.freedesktop.org/patch/317255/?series=62326&rev=3 Changes since original patch: * Remove unused intel_dp variable in intel_dp_aux_setup_backlight() * Fix checkpatch issues * Make sure that we rewrite the pwmgen bit count whenever we bring the panel out of D3 mode v2 by Jani: * rebase * fix readb return value check Cc: Furquan Shaikh Tested-by: AceLan Kao Tested-by: Perry Yuan Signed-off-by: Lyude Paul Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20200116211623.53799-2-lyude@redhat.com --- .../drm/i915/display/intel_display_types.h | 3 + .../drm/i915/display/intel_dp_aux_backlight.c | 139 ++++++++++++------ 2 files changed, 95 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 888ea8a170d1..778bd30743e5 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -214,6 +214,9 @@ struct intel_panel { u8 controller; /* bxt+ only */ struct pwm_device *pwm; + /* DPCD backlight */ + u8 pwmgen_bit_count; + struct backlight_device *device; /* Connector and platform specific backlight functions */ diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c index 7c653f8c307f..345eed641455 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -111,61 +111,28 @@ static bool intel_dp_aux_set_pwm_freq(struct intel_connector *connector) { struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); - int freq, fxp, fxp_min, fxp_max, fxp_actual, f = 1; - u8 pn, pn_min, pn_max; + const u8 pn = connector->panel.backlight.pwmgen_bit_count; + int freq, fxp, f, fxp_actual, fxp_min, fxp_max; - /* Find desired value of (F x P) - * Note that, if F x P is out of supported range, the maximum value or - * minimum value will applied automatically. So no need to check that. - */ freq = dev_priv->vbt.backlight.pwm_freq_hz; - DRM_DEBUG_KMS("VBT defined backlight frequency %u Hz\n", freq); if (!freq) { DRM_DEBUG_KMS("Use panel default backlight frequency\n"); return false; } fxp = DIV_ROUND_CLOSEST(KHz(DP_EDP_BACKLIGHT_FREQ_BASE_KHZ), freq); + f = clamp(DIV_ROUND_CLOSEST(fxp, 1 << pn), 1, 255); + fxp_actual = f << pn; - /* Use highest possible value of Pn for more granularity of brightness - * adjustment while satifying the conditions below. - * - Pn is in the range of Pn_min and Pn_max - * - F is in the range of 1 and 255 - * - FxP is within 25% of desired value. - * Note: 25% is arbitrary value and may need some tweak. - */ - if (drm_dp_dpcd_readb(&intel_dp->aux, - DP_EDP_PWMGEN_BIT_COUNT_CAP_MIN, &pn_min) != 1) { - DRM_DEBUG_KMS("Failed to read pwmgen bit count cap min\n"); - return false; - } - if (drm_dp_dpcd_readb(&intel_dp->aux, - DP_EDP_PWMGEN_BIT_COUNT_CAP_MAX, &pn_max) != 1) { - DRM_DEBUG_KMS("Failed to read pwmgen bit count cap max\n"); - return false; - } - pn_min &= DP_EDP_PWMGEN_BIT_COUNT_MASK; - pn_max &= DP_EDP_PWMGEN_BIT_COUNT_MASK; - + /* Ensure frequency is within 25% of desired value */ fxp_min = DIV_ROUND_CLOSEST(fxp * 3, 4); fxp_max = DIV_ROUND_CLOSEST(fxp * 5, 4); - if (fxp_min < (1 << pn_min) || (255 << pn_max) < fxp_max) { - DRM_DEBUG_KMS("VBT defined backlight frequency out of range\n"); + + if (fxp_min > fxp_actual || fxp_actual > fxp_max) { + DRM_DEBUG_KMS("Actual frequency out of range\n"); return false; } - for (pn = pn_max; pn >= pn_min; pn--) { - f = clamp(DIV_ROUND_CLOSEST(fxp, 1 << pn), 1, 255); - fxp_actual = f << pn; - if (fxp_min <= fxp_actual && fxp_actual <= fxp_max) - break; - } - - if (drm_dp_dpcd_writeb(&intel_dp->aux, - DP_EDP_PWMGEN_BIT_COUNT, pn) < 0) { - DRM_DEBUG_KMS("Failed to write aux pwmgen bit count\n"); - return false; - } if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_EDP_BACKLIGHT_FREQ_SET, (u8) f) < 0) { DRM_DEBUG_KMS("Failed to write aux backlight freq\n"); @@ -179,6 +146,7 @@ static void intel_dp_aux_enable_backlight(const struct intel_crtc_state *crtc_st { struct intel_connector *connector = to_intel_connector(conn_state->connector); struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); + struct intel_panel *panel = &connector->panel; u8 dpcd_buf, new_dpcd_buf, edp_backlight_mode; if (drm_dp_dpcd_readb(&intel_dp->aux, @@ -197,6 +165,12 @@ static void intel_dp_aux_enable_backlight(const struct intel_crtc_state *crtc_st case DP_EDP_BACKLIGHT_CONTROL_MODE_PRODUCT: new_dpcd_buf &= ~DP_EDP_BACKLIGHT_CONTROL_MODE_MASK; new_dpcd_buf |= DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD; + + if (drm_dp_dpcd_writeb(&intel_dp->aux, + DP_EDP_PWMGEN_BIT_COUNT, + panel->backlight.pwmgen_bit_count) < 0) + DRM_DEBUG_KMS("Failed to write aux pwmgen bit count\n"); + break; /* Do nothing when it is already DPCD mode */ @@ -226,20 +200,91 @@ static void intel_dp_aux_disable_backlight(const struct drm_connector_state *old false); } +static u32 intel_dp_aux_calc_max_backlight(struct intel_connector *connector) +{ + struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); + struct intel_panel *panel = &connector->panel; + u32 max_backlight = 0; + int freq, fxp, fxp_min, fxp_max, fxp_actual, f = 1; + u8 pn, pn_min, pn_max; + + if (drm_dp_dpcd_readb(&intel_dp->aux, DP_EDP_PWMGEN_BIT_COUNT, &pn) == 1) { + pn &= DP_EDP_PWMGEN_BIT_COUNT_MASK; + max_backlight = (1 << pn) - 1; + } + + /* Find desired value of (F x P) + * Note that, if F x P is out of supported range, the maximum value or + * minimum value will applied automatically. So no need to check that. + */ + freq = i915->vbt.backlight.pwm_freq_hz; + DRM_DEBUG_KMS("VBT defined backlight frequency %u Hz\n", freq); + if (!freq) { + DRM_DEBUG_KMS("Use panel default backlight frequency\n"); + return max_backlight; + } + + fxp = DIV_ROUND_CLOSEST(KHz(DP_EDP_BACKLIGHT_FREQ_BASE_KHZ), freq); + + /* Use highest possible value of Pn for more granularity of brightness + * adjustment while satifying the conditions below. + * - Pn is in the range of Pn_min and Pn_max + * - F is in the range of 1 and 255 + * - FxP is within 25% of desired value. + * Note: 25% is arbitrary value and may need some tweak. + */ + if (drm_dp_dpcd_readb(&intel_dp->aux, + DP_EDP_PWMGEN_BIT_COUNT_CAP_MIN, &pn_min) != 1) { + DRM_DEBUG_KMS("Failed to read pwmgen bit count cap min\n"); + return max_backlight; + } + if (drm_dp_dpcd_readb(&intel_dp->aux, + DP_EDP_PWMGEN_BIT_COUNT_CAP_MAX, &pn_max) != 1) { + DRM_DEBUG_KMS("Failed to read pwmgen bit count cap max\n"); + return max_backlight; + } + pn_min &= DP_EDP_PWMGEN_BIT_COUNT_MASK; + pn_max &= DP_EDP_PWMGEN_BIT_COUNT_MASK; + + fxp_min = DIV_ROUND_CLOSEST(fxp * 3, 4); + fxp_max = DIV_ROUND_CLOSEST(fxp * 5, 4); + if (fxp_min < (1 << pn_min) || (255 << pn_max) < fxp_max) { + DRM_DEBUG_KMS("VBT defined backlight frequency out of range\n"); + return max_backlight; + } + + for (pn = pn_max; pn >= pn_min; pn--) { + f = clamp(DIV_ROUND_CLOSEST(fxp, 1 << pn), 1, 255); + fxp_actual = f << pn; + if (fxp_min <= fxp_actual && fxp_actual <= fxp_max) + break; + } + + DRM_DEBUG_KMS("Using eDP pwmgen bit count of %d\n", pn); + if (drm_dp_dpcd_writeb(&intel_dp->aux, + DP_EDP_PWMGEN_BIT_COUNT, pn) < 0) { + DRM_DEBUG_KMS("Failed to write aux pwmgen bit count\n"); + return max_backlight; + } + panel->backlight.pwmgen_bit_count = pn; + + max_backlight = (1 << pn) - 1; + + return max_backlight; +} + static int intel_dp_aux_setup_backlight(struct intel_connector *connector, enum pipe pipe) { - struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); struct intel_panel *panel = &connector->panel; - if (intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT) - panel->backlight.max = 0xFFFF; - else - panel->backlight.max = 0xFF; + panel->backlight.max = intel_dp_aux_calc_max_backlight(connector); + if (!panel->backlight.max) + return -ENODEV; panel->backlight.min = 0; panel->backlight.level = intel_dp_aux_get_backlight(connector); - panel->backlight.enabled = panel->backlight.level != 0; return 0; From 79946723092bde318ff11b3e57a02ba13a30b17e Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Thu, 16 Jan 2020 16:16:09 -0500 Subject: [PATCH 0057/1537] drm/i915: Assume 100% brightness when not in DPCD control mode Currently we always determine the initial panel brightness level by simply reading the value from DP_EDP_BACKLIGHT_BRIGHTNESS_MSB/LSB. This seems wrong though, because if the panel is not currently in DPCD control mode there's not really any reason why there would be any brightness value programmed in the first place. This appears to be the case on the Lenovo ThinkPad X1 Extreme 2nd Generation, where the default value in these registers is always 0 on boot despite the fact the panel runs at max brightness by default. Getting the initial brightness value correct here is important as well, since the panel on this laptop doesn't behave well if it's ever put into DPCD control mode while the brightness level is programmed to 0. So, let's fix this by checking what the current backlight control mode is before reading the brightness level. If it's in DPCD control mode, we return the programmed brightness level. Otherwise we assume 100% brightness and return the highest possible brightness level. This also prevents us from accidentally programming a brightness level of 0. This is one of the many fixes that gets backlight controls working on the ThinkPad X1 Extreme 2nd Generation with optional 4K AMOLED screen. Changes since v1: * s/DP_EDP_DISPLAY_CONTROL_REGISTER/DP_EDP_BACKLIGHT_MODE_SET_REGISTER/ - Jani Tested-by: AceLan Kao Tested-by: Perry Yuan Signed-off-by: Lyude Paul Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20200116211623.53799-3-lyude@redhat.com --- .../drm/i915/display/intel_dp_aux_backlight.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c index 345eed641455..5d4db5f8a165 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -59,8 +59,25 @@ static u32 intel_dp_aux_get_backlight(struct intel_connector *connector) { struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); u8 read_val[2] = { 0x0 }; + u8 mode_reg; u16 level = 0; + if (drm_dp_dpcd_readb(&intel_dp->aux, + DP_EDP_BACKLIGHT_MODE_SET_REGISTER, + &mode_reg) != 1) { + DRM_DEBUG_KMS("Failed to read the DPCD register 0x%x\n", + DP_EDP_BACKLIGHT_MODE_SET_REGISTER); + return 0; + } + + /* + * If we're not in DPCD control mode yet, the programmed brightness + * value is meaningless and we should assume max brightness + */ + if ((mode_reg & DP_EDP_BACKLIGHT_CONTROL_MODE_MASK) != + DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) + return connector->panel.backlight.max; + if (drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_BACKLIGHT_BRIGHTNESS_MSB, &read_val, sizeof(read_val)) < 0) { DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n", From 662884a9ad992240b8169624aae1b0cc273edc30 Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Thu, 16 Jan 2020 16:16:10 -0500 Subject: [PATCH 0058/1537] drm/i915: Fix DPCD register order in intel_dp_aux_enable_backlight() For eDP panels, it appears it's expected that so long as the panel is in DPCD control mode that the brightness value is never set to 0. Instead, if the desired effect is to set the panel's backlight to 0 we're expected to simply turn off the backlight through the DP_EDP_DISPLAY_CONTROL_REGISTER. We already do the latter correctly in intel_dp_aux_disable_backlight(). But, we make the mistake of writing the DPCD registers in the wrong order when enabling the backlight in intel_dp_aux_enable_backlight() since we currently enable the backlight through DP_EDP_DISPLAY_CONTROL_REGISTER before writing the brightness level. On the X1 Extreme 2nd Generation, this appears to have the potential of confusing the panel in such a way that further attempts to set the brightness don't actually change the backlight as expected and leave it off. Presumably, this happens because the incorrect register writing order briefly leaves the panel with DPCD mode enabled and a 0 brightness level set. So, reverse the order we write the DPCD registers when enabling the panel backlight so that we write the brightness value first, and enable the backlight second. This fix appears to be the final bit needed to get the backlight on the ThinkPad X1 Extreme 2nd Generation's AMOLED screen working. Tested-by: AceLan Kao Tested-by: Perry Yuan Signed-off-by: Lyude Paul Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20200116211623.53799-4-lyude@redhat.com --- drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c index 5d4db5f8a165..77a759361c5c 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -207,8 +207,9 @@ static void intel_dp_aux_enable_backlight(const struct intel_crtc_state *crtc_st } } + intel_dp_aux_set_backlight(conn_state, + connector->panel.backlight.level); set_aux_backlight_enable(intel_dp, true); - intel_dp_aux_set_backlight(conn_state, connector->panel.backlight.level); } static void intel_dp_aux_disable_backlight(const struct drm_connector_state *old_conn_state) From 9ac7d53d70a2b4f43360e3aa0f14a2514339328f Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Thu, 16 Jan 2020 16:16:12 -0500 Subject: [PATCH 0059/1537] drm/i915: Auto detect DPCD backlight support by default Turns out we actually already have some companies, such as Lenovo, shipping machines with AMOLED screens that don't allow controlling the backlight through the usual PWM interface and only allow controlling it through the standard EDP DPCD interface. One example of one of these laptops is the X1 Extreme 2nd Generation. Since we've got systems that need this turned on by default now to have backlight controls working out of the box, let's start auto-detecting it for systems by default based on what the VBT tells us. We do this by changing the default value for the enable_dpcd_backlight module param from 0 to -1. Tested-by: AceLan Kao Tested-by: Perry Yuan Signed-off-by: Lyude Paul Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20200116211623.53799-6-lyude@redhat.com --- drivers/gpu/drm/i915/i915_params.c | 2 +- drivers/gpu/drm/i915/i915_params.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 64009e99073d..905decc36e53 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -172,7 +172,7 @@ i915_param_named_unsafe(inject_probe_failure, uint, 0400, i915_param_named(enable_dpcd_backlight, int, 0600, "Enable support for DPCD backlight control" - "(-1=use per-VBT LFP backlight type setting, 0=disabled [default], 1=enabled)"); + "(-1=use per-VBT LFP backlight type setting [default], 0=disabled, 1=enabled)"); #if IS_ENABLED(CONFIG_DRM_I915_GVT) i915_param_named(enable_gvt, bool, 0400, diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index be6089e4f9e6..947d0a38fa3c 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -66,7 +66,7 @@ struct drm_printer; param(int, reset, 3, 0600) \ param(unsigned int, inject_probe_failure, 0, 0600) \ param(int, fastboot, -1, 0600) \ - param(int, enable_dpcd_backlight, 0, 0600) \ + param(int, enable_dpcd_backlight, -1, 0600) \ param(char *, force_probe, CONFIG_DRM_I915_FORCE_PROBE, 0400) \ param(unsigned long, fake_lmem_start, 0, 0400) \ /* leave bools at the end to not create holes */ \ From c53aec2bcc7487437984e4d13e4fc15c4cc95047 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 17 Jan 2020 10:21:45 +0000 Subject: [PATCH 0060/1537] drm/i915: Include the debugfs params header for its own definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/gpu/drm/i915/i915_debugfs_params.c:228:15: warning: symbol 'i915_debugfs_params' was not declared. Should it be static? drivers/gpu/drm/i915/i915_debugfs_params.c:228:16: error: no previous prototype for ‘i915_debugfs_params’ [-Werror=missing-prototypes] 228 | struct dentry *i915_debugfs_params(struct drm_i915_private *i915) Signed-off-by: Chris Wilson Cc: Jani Nikula Reviewed-by: Jani Nikula Fixes: c43c5a8818d4 ("drm/i915/params: add i915 parameters to debugfs") Link: https://patchwork.freedesktop.org/patch/msgid/20200117102145.2948244-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs_params.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/i915_debugfs_params.c b/drivers/gpu/drm/i915/i915_debugfs_params.c index 12cbdbdf4d80..62b2c5f0495d 100644 --- a/drivers/gpu/drm/i915/i915_debugfs_params.c +++ b/drivers/gpu/drm/i915/i915_debugfs_params.c @@ -5,6 +5,7 @@ #include +#include "i915_debugfs_params.h" #include "i915_drv.h" #include "i915_params.h" From 04062c58faafddf62006c6f8e5077dc050e8207e Mon Sep 17 00:00:00 2001 From: Zhang Xiaoxu Date: Fri, 17 Jan 2020 15:34:36 +0800 Subject: [PATCH 0061/1537] drm/i915: Fix i915_error_state_store error defination Since commit 742379c0c4001 ("drm/i915: Start chopping up the GPU error capture"), function 'i915_error_state_store' was defined and used with only one parameter. But if no 'CONFIG_DRM_I915_CAPTURE_ERROR', this function was defined with two parameter. This may lead compile error. This patch fix it. Reported-by: Hulk Robot Signed-off-by: Zhang Xiaoxu Reviewed-by: Andi Shyti Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20200117073436.6507-1-zhangxiaoxu5@huawei.com --- drivers/gpu/drm/i915/i915_gpu_error.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gpu_error.h b/drivers/gpu/drm/i915/i915_gpu_error.h index 9109004956bd..41c1475e1500 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.h +++ b/drivers/gpu/drm/i915/i915_gpu_error.h @@ -314,8 +314,7 @@ i915_vma_capture_finish(struct intel_gt_coredump *gt, } static inline void -i915_error_state_store(struct drm_i915_private *i915, - struct i915_gpu_coredump *error) +i915_error_state_store(struct i915_gpu_coredump *error) { } From f1766e3a78c5edbf8a24baf4bb11d78ed9cf49dc Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 17 Jan 2020 10:16:39 +0000 Subject: [PATCH 0062/1537] drm/i915: Fix typo in kerneldoc function name A forgetful copy'n'paste left the name of the old function intact, and did not introduce the new function 'i915_request_is_ready' Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Reviewed-by: Matthew Auld Link: https://patchwork.freedesktop.org/patch/msgid/20200117101639.2908469-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_request.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h index f57eadcf3583..da8420f03232 100644 --- a/drivers/gpu/drm/i915/i915_request.h +++ b/drivers/gpu/drm/i915/i915_request.h @@ -479,7 +479,7 @@ static inline bool i915_request_is_running(const struct i915_request *rq) } /** - * i915_request_is_running - check if the request is ready for execution + * i915_request_is_ready - check if the request is ready for execution * @rq: the request * * Upon construction, the request is instructed to wait upon various From 416d3838f76b719cb47f076df73691eeac59a6ea Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 17 Jan 2020 11:06:02 +0000 Subject: [PATCH 0063/1537] drm/i915: Satisfy smatch that a loop has at least one iteration Smatch worries that the engine->mask may be 0 leading to the loop being shortcircuited leaving the next pointer unset, drivers/gpu/drm/i915/i915_active.c:667 i915_active_acquire_preallocate_barrier() error: uninitialized symbol 'next'. Assert that mask is not 0 and smatch can then verify that next must be initialised before use. Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Reviewed-by: Matthew Auld Link: https://patchwork.freedesktop.org/patch/msgid/20200117110603.2982286-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_active.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c index f3da5c06f331..ace55d5d4ca7 100644 --- a/drivers/gpu/drm/i915/i915_active.c +++ b/drivers/gpu/drm/i915/i915_active.c @@ -621,6 +621,7 @@ int i915_active_acquire_preallocate_barrier(struct i915_active *ref, * We can then use the preallocated nodes in * i915_active_acquire_barrier() */ + GEM_BUG_ON(!mask); for_each_engine_masked(engine, gt, mask, tmp) { u64 idx = engine->kernel_context->timeline->fence_context; struct active_node *node; From 1b9fc94a7751259398e006c2c2f3c7fb28e5ff7a Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Fri, 17 Jan 2020 08:20:35 +0000 Subject: [PATCH 0064/1537] drm/i915/guc: Don't GEM_BUG_ON on corrupted G2H CTB We should never BUG_ON on any corruption in CTB descriptor as data there can be also modified by the GuC. Instead we can use flag "is_in_error" to indicate that we will not process any further messages over this CTB (until reset). While here move descriptor error reporting to the function that actually touches that descriptor. Note that unexpected content of the specific CT messages, that still complies with generic CT message format, shall not trigger disabling whole CTB, as that might just indicate new unsupported message types. v2: drop redundant message (Daniele) Signed-off-by: Michal Wajdeczko Cc: Chris Wilson Cc: Daniele Ceraolo Spurio Reviewed-by: Daniele Ceraolo Spurio Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20200117082039.65644-2-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 38 +++++++++++++---------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c index a55c336cc5ef..46e4faf1e11c 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c @@ -578,19 +578,25 @@ static inline bool ct_header_is_response(u32 header) static int ctb_read(struct intel_guc_ct_buffer *ctb, u32 *data) { struct guc_ct_buffer_desc *desc = ctb->desc; - u32 head = desc->head / 4; /* in dwords */ - u32 tail = desc->tail / 4; /* in dwords */ - u32 size = desc->size / 4; /* in dwords */ + u32 head = desc->head; + u32 tail = desc->tail; + u32 size = desc->size; u32 *cmds = ctb->cmds; - s32 available; /* in dwords */ + s32 available; unsigned int len; unsigned int i; - GEM_BUG_ON(desc->size % 4); - GEM_BUG_ON(desc->head % 4); - GEM_BUG_ON(desc->tail % 4); - GEM_BUG_ON(tail >= size); - GEM_BUG_ON(head >= size); + if (unlikely(desc->is_in_error)) + return -EPIPE; + + if (unlikely(!IS_ALIGNED(head | tail | size, 4) || + (tail | head) >= size)) + goto corrupted; + + /* later calculations will be done in dwords */ + head /= 4; + tail /= 4; + size /= 4; /* tail == head condition indicates empty */ available = tail - head; @@ -615,7 +621,7 @@ static int ctb_read(struct intel_guc_ct_buffer *ctb, u32 *data) size - head : available - 1), &cmds[head], 4 * (head + available - 1 > size ? available - 1 - size + head : 0), &cmds[0]); - return -EPROTO; + goto corrupted; } for (i = 1; i < len; i++) { @@ -626,6 +632,12 @@ static int ctb_read(struct intel_guc_ct_buffer *ctb, u32 *data) desc->head = head * 4; return 0; + +corrupted: + DRM_ERROR("CT: Corrupted descriptor addr=%#x head=%u tail=%u size=%u\n", + desc->addr, desc->head, desc->tail, desc->size); + desc->is_in_error = 1; + return -EPIPE; } /** @@ -836,10 +848,4 @@ void intel_guc_ct_event_handler(struct intel_guc_ct *ct) else err = ct_handle_request(ct, msg); } while (!err); - - if (GEM_WARN_ON(err == -EPROTO)) { - CT_ERROR(ct, "Corrupted message: %#x\n", msg[0]); - ctb->desc->is_in_error = 1; - } } - From 6a327cb18692f5741e023196310ef8e480da7f9a Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Fri, 17 Jan 2020 08:20:36 +0000 Subject: [PATCH 0065/1537] drm/i915/guc: Don't pass CTB while writing Since we only have one SEND buffer we don't need to explicitly pass it to the write function. Signed-off-by: Michal Wajdeczko Cc: Chris Wilson Cc: Daniele Ceraolo Spurio Reviewed-by: Daniele Ceraolo Spurio Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20200117082039.65644-3-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c index 46e4faf1e11c..a373ca1779cb 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c @@ -311,12 +311,13 @@ static u32 ct_get_next_fence(struct intel_guc_ct *ct) * ^-----------------len-------------------^ */ -static int ctb_write(struct intel_guc_ct_buffer *ctb, - const u32 *action, - u32 len /* in dwords */, - u32 fence, - bool want_response) +static int ct_write(struct intel_guc_ct *ct, + const u32 *action, + u32 len /* in dwords */, + u32 fence, + bool want_response) { + struct intel_guc_ct_buffer *ctb = &ct->ctbs[CTB_SEND]; struct guc_ct_buffer_desc *desc = ctb->desc; u32 head = desc->head / 4; /* in dwords */ u32 tail = desc->tail / 4; /* in dwords */ @@ -492,7 +493,7 @@ static int ct_send(struct intel_guc_ct *ct, list_add_tail(&request.link, &ct->requests.pending); spin_unlock_irqrestore(&ct->requests.lock, flags); - err = ctb_write(ctb, action, len, fence, !!response_buf); + err = ct_write(ct, action, len, fence, !!response_buf); if (unlikely(err)) goto unlink; From 235198d7c9bc9d632d801bd8b17cecf488212cc1 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Fri, 17 Jan 2020 08:20:37 +0000 Subject: [PATCH 0066/1537] drm/i915/guc: Don't pass CTB while reading Since we only have one RECV buffer we don't need to explicitly pass it to the read function. Signed-off-by: Michal Wajdeczko Cc: Chris Wilson Cc: Daniele Ceraolo Spurio Reviewed-by: Daniele Ceraolo Spurio Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20200117082039.65644-4-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c index a373ca1779cb..a381fd07668a 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c @@ -576,8 +576,9 @@ static inline bool ct_header_is_response(u32 header) return !!(header & GUC_CT_MSG_IS_RESPONSE); } -static int ctb_read(struct intel_guc_ct_buffer *ctb, u32 *data) +static int ct_read(struct intel_guc_ct *ct, u32 *data) { + struct intel_guc_ct_buffer *ctb = &ct->ctbs[CTB_RECV]; struct guc_ct_buffer_desc *desc = ctb->desc; u32 head = desc->head; u32 tail = desc->tail; @@ -830,7 +831,6 @@ static int ct_handle_request(struct intel_guc_ct *ct, const u32 *msg) */ void intel_guc_ct_event_handler(struct intel_guc_ct *ct) { - struct intel_guc_ct_buffer *ctb = &ct->ctbs[CTB_RECV]; u32 msg[GUC_CT_MSG_LEN_MASK + 1]; /* one extra dw for the header */ int err = 0; @@ -840,7 +840,7 @@ void intel_guc_ct_event_handler(struct intel_guc_ct *ct) } do { - err = ctb_read(ctb, msg); + err = ct_read(ct, msg); if (err) break; From d624d401772d493202dce258fe48ee01ef43bae8 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Fri, 17 Jan 2020 08:20:38 +0000 Subject: [PATCH 0067/1537] drm/i915/guc: Switch to CT_ERROR in ct_read MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As we now have "ct" available in ct_read function we can switch from generic DRM_ERROR to our custom CT_ERROR. Signed-off-by: Michal Wajdeczko Cc: Chris Wilson Cc: Daniele Ceraolo Spurio Reviewed-by: Piotr Piórkowski Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20200117082039.65644-5-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c index a381fd07668a..a0aa79b3a876 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c @@ -617,12 +617,12 @@ static int ct_read(struct intel_guc_ct *ct, u32 *data) /* message len with header */ len = ct_header_get_len(data[0]) + 1; if (unlikely(len > (u32)available)) { - DRM_ERROR("CT: incomplete message %*ph %*ph %*ph\n", - 4, data, - 4 * (head + available - 1 > size ? - size - head : available - 1), &cmds[head], - 4 * (head + available - 1 > size ? - available - 1 - size + head : 0), &cmds[0]); + CT_ERROR(ct, "Incomplete message %*ph %*ph %*ph\n", + 4, data, + 4 * (head + available - 1 > size ? + size - head : available - 1), &cmds[head], + 4 * (head + available - 1 > size ? + available - 1 - size + head : 0), &cmds[0]); goto corrupted; } @@ -636,8 +636,8 @@ static int ct_read(struct intel_guc_ct *ct, u32 *data) return 0; corrupted: - DRM_ERROR("CT: Corrupted descriptor addr=%#x head=%u tail=%u size=%u\n", - desc->addr, desc->head, desc->tail, desc->size); + CT_ERROR(ct, "Corrupted descriptor addr=%#x head=%u tail=%u size=%u\n", + desc->addr, desc->head, desc->tail, desc->size); desc->is_in_error = 1; return -EPIPE; } From 77b20896d57e91fbfa98b40ee5935b0a044aa29d Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Fri, 17 Jan 2020 08:20:39 +0000 Subject: [PATCH 0068/1537] drm/i915/guc: Introduce CT_DEBUG As we now have "ct" available almost in all functions we can start using dev variants of logs also for debug. Signed-off-by: Michal Wajdeczko Cc: Chris Wilson Cc: Daniele Ceraolo Spurio Reviewed-by: Daniele Ceraolo Spurio Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20200117082039.65644-6-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 41 +++++++++++------------ 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c index a0aa79b3a876..02b543377e2b 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c @@ -10,9 +10,10 @@ #define CT_ERROR(_ct, _fmt, ...) \ DRM_DEV_ERROR(ct_to_dev(_ct), "CT: " _fmt, ##__VA_ARGS__) #ifdef CONFIG_DRM_I915_DEBUG_GUC -#define CT_DEBUG_DRIVER(...) DRM_DEBUG_DRIVER(__VA_ARGS__) +#define CT_DEBUG(_ct, _fmt, ...) \ + DRM_DEV_DEBUG_DRIVER(ct_to_dev(_ct), "CT: " _fmt, ##__VA_ARGS__) #else -#define CT_DEBUG_DRIVER(...) do { } while (0) +#define CT_DEBUG(...) do { } while (0) #endif struct ct_request { @@ -81,7 +82,6 @@ static inline const char *guc_ct_buffer_type_to_str(u32 type) static void guc_ct_buffer_desc_init(struct guc_ct_buffer_desc *desc, u32 cmds_addr, u32 size) { - CT_DEBUG_DRIVER("CT: init addr=%#x size=%u\n", cmds_addr, size); memset(desc, 0, sizeof(*desc)); desc->addr = cmds_addr; desc->size = size; @@ -90,8 +90,6 @@ static void guc_ct_buffer_desc_init(struct guc_ct_buffer_desc *desc, static void guc_ct_buffer_desc_reset(struct guc_ct_buffer_desc *desc) { - CT_DEBUG_DRIVER("CT: desc %p reset head=%u tail=%u\n", - desc, desc->head, desc->tail); desc->head = 0; desc->tail = 0; desc->is_in_error = 0; @@ -189,8 +187,7 @@ int intel_guc_ct_init(struct intel_guc_ct *ct) return err; } - CT_DEBUG_DRIVER("CT: vma base=%#x\n", - intel_guc_ggtt_offset(guc, ct->vma)); + CT_DEBUG(ct, "vma base=%#x\n", intel_guc_ggtt_offset(guc, ct->vma)); /* store pointers to desc and cmds */ for (i = 0; i < ARRAY_SIZE(ct->ctbs); i++) { @@ -224,7 +221,7 @@ void intel_guc_ct_fini(struct intel_guc_ct *ct) int intel_guc_ct_enable(struct intel_guc_ct *ct) { struct intel_guc *guc = ct_to_guc(ct); - u32 base; + u32 base, cmds, size; int err; int i; @@ -239,9 +236,10 @@ int intel_guc_ct_enable(struct intel_guc_ct *ct) */ for (i = 0; i < ARRAY_SIZE(ct->ctbs); i++) { GEM_BUG_ON((i != CTB_SEND) && (i != CTB_RECV)); - guc_ct_buffer_desc_init(ct->ctbs[i].desc, - base + PAGE_SIZE/4 * i + PAGE_SIZE/2, - PAGE_SIZE/4); + cmds = base + PAGE_SIZE / 4 * i + PAGE_SIZE / 2; + size = PAGE_SIZE / 4; + CT_DEBUG(ct, "%d: addr=%#x size=%u\n", i, cmds, size); + guc_ct_buffer_desc_init(ct->ctbs[i].desc, cmds, size); } /* @@ -356,9 +354,8 @@ static int ct_write(struct intel_guc_ct *ct, (want_response ? GUC_CT_MSG_SEND_STATUS : 0) | (action[0] << GUC_CT_MSG_ACTION_SHIFT); - CT_DEBUG_DRIVER("CT: writing %*ph %*ph %*ph\n", - 4, &header, 4, &fence, - 4 * (len - 1), &action[1]); + CT_DEBUG(ct, "writing %*ph %*ph %*ph\n", + 4, &header, 4, &fence, 4 * (len - 1), &action[1]); cmds[tail] = header; tail = (tail + 1) % size; @@ -553,8 +550,8 @@ int intel_guc_ct_send(struct intel_guc_ct *ct, const u32 *action, u32 len, CT_ERROR(ct, "Sending action %#x failed (err=%d status=%#X)\n", action[0], ret, status); } else if (unlikely(ret)) { - CT_DEBUG_DRIVER("CT: send action %#x returned %d (%#x)\n", - action[0], ret, ret); + CT_DEBUG(ct, "send action %#x returned %d (%#x)\n", + action[0], ret, ret); } mutex_unlock(&guc->send_mutex); @@ -608,7 +605,7 @@ static int ct_read(struct intel_guc_ct *ct, u32 *data) /* beware of buffer wrap case */ if (unlikely(available < 0)) available += size; - CT_DEBUG_DRIVER("CT: available %d (%u:%u)\n", available, head, tail); + CT_DEBUG(ct, "available %d (%u:%u)\n", available, head, tail); GEM_BUG_ON(available < 0); data[0] = cmds[head]; @@ -630,7 +627,7 @@ static int ct_read(struct intel_guc_ct *ct, u32 *data) data[i] = cmds[head]; head = (head + 1) % size; } - CT_DEBUG_DRIVER("CT: received %*ph\n", 4 * len, data); + CT_DEBUG(ct, "received %*ph\n", 4 * len, data); desc->head = head * 4; return 0; @@ -690,13 +687,13 @@ static int ct_handle_response(struct intel_guc_ct *ct, const u32 *msg) return -EPROTO; } - CT_DEBUG_DRIVER("CT: response fence %u status %#x\n", fence, status); + CT_DEBUG(ct, "response fence %u status %#x\n", fence, status); spin_lock(&ct->requests.lock); list_for_each_entry(req, &ct->requests.pending, link) { if (unlikely(fence != req->fence)) { - CT_DEBUG_DRIVER("CT: request %u awaits response\n", - req->fence); + CT_DEBUG(ct, "request %u awaits response\n", + req->fence); continue; } if (unlikely(datalen > req->response_len)) { @@ -724,7 +721,7 @@ static void ct_process_request(struct intel_guc_ct *ct, struct intel_guc *guc = ct_to_guc(ct); int ret; - CT_DEBUG_DRIVER("CT: request %x %*ph\n", action, 4 * len, payload); + CT_DEBUG(ct, "request %x %*ph\n", action, 4 * len, payload); switch (action) { case INTEL_GUC_ACTION_DEFAULT: From aee2eeeb18eb67b5074fba3501761493b08668a1 Mon Sep 17 00:00:00 2001 From: Wambui Karuga Date: Thu, 9 Jan 2020 12:06:42 +0300 Subject: [PATCH 0069/1537] drm/i915: conversion to new logging macros in i915/i915_vgpu.c Replace the use of printk based logging macros with the struct drm_device based macros in i915/i915_vgpu.c Signed-off-by: Wambui Karuga Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/45e8bffff8cbffd72ed41901c3db9f7f6dbe79f3.1578560355.git.wambui.karugax@gmail.com --- drivers/gpu/drm/i915/i915_vgpu.c | 41 +++++++++++++++++++------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c index 968be26735c5..4afe21662266 100644 --- a/drivers/gpu/drm/i915/i915_vgpu.c +++ b/drivers/gpu/drm/i915/i915_vgpu.c @@ -77,7 +77,8 @@ void i915_detect_vgpu(struct drm_i915_private *dev_priv) shared_area = pci_iomap_range(pdev, 0, VGT_PVINFO_PAGE, VGT_PVINFO_SIZE); if (!shared_area) { - DRM_ERROR("failed to map MMIO bar to check for VGT\n"); + drm_err(&dev_priv->drm, + "failed to map MMIO bar to check for VGT\n"); return; } @@ -87,7 +88,7 @@ void i915_detect_vgpu(struct drm_i915_private *dev_priv) version_major = readw(shared_area + vgtif_offset(version_major)); if (version_major < VGT_VERSION_MAJOR) { - DRM_INFO("VGT interface version mismatch!\n"); + drm_info(&dev_priv->drm, "VGT interface version mismatch!\n"); goto out; } @@ -95,7 +96,7 @@ void i915_detect_vgpu(struct drm_i915_private *dev_priv) dev_priv->vgpu.active = true; mutex_init(&dev_priv->vgpu.lock); - DRM_INFO("Virtual GPU for Intel GVT-g detected.\n"); + drm_info(&dev_priv->drm, "Virtual GPU for Intel GVT-g detected.\n"); out: pci_iounmap(pdev, shared_area); @@ -120,13 +121,15 @@ static struct _balloon_info_ bl_info; static void vgt_deballoon_space(struct i915_ggtt *ggtt, struct drm_mm_node *node) { + struct drm_i915_private *dev_priv = ggtt->vm.i915; if (!drm_mm_node_allocated(node)) return; - DRM_DEBUG_DRIVER("deballoon space: range [0x%llx - 0x%llx] %llu KiB.\n", - node->start, - node->start + node->size, - node->size / 1024); + drm_dbg(&dev_priv->drm, + "deballoon space: range [0x%llx - 0x%llx] %llu KiB.\n", + node->start, + node->start + node->size, + node->size / 1024); ggtt->vm.reserved -= node->size; drm_mm_remove_node(node); @@ -141,12 +144,13 @@ static void vgt_deballoon_space(struct i915_ggtt *ggtt, */ void intel_vgt_deballoon(struct i915_ggtt *ggtt) { + struct drm_i915_private *dev_priv = ggtt->vm.i915; int i; if (!intel_vgpu_active(ggtt->vm.i915)) return; - DRM_DEBUG("VGT deballoon.\n"); + drm_dbg(&dev_priv->drm, "VGT deballoon.\n"); for (i = 0; i < 4; i++) vgt_deballoon_space(ggtt, &bl_info.space[i]); @@ -156,13 +160,15 @@ static int vgt_balloon_space(struct i915_ggtt *ggtt, struct drm_mm_node *node, unsigned long start, unsigned long end) { + struct drm_i915_private *dev_priv = ggtt->vm.i915; unsigned long size = end - start; int ret; if (start >= end) return -EINVAL; - DRM_INFO("balloon space: range [ 0x%lx - 0x%lx ] %lu KiB.\n", + drm_info(&dev_priv->drm, + "balloon space: range [ 0x%lx - 0x%lx ] %lu KiB.\n", start, end, size / 1024); ret = i915_gem_gtt_reserve(&ggtt->vm, node, size, start, I915_COLOR_UNEVICTABLE, @@ -219,7 +225,8 @@ static int vgt_balloon_space(struct i915_ggtt *ggtt, */ int intel_vgt_balloon(struct i915_ggtt *ggtt) { - struct intel_uncore *uncore = &ggtt->vm.i915->uncore; + struct drm_i915_private *dev_priv = ggtt->vm.i915; + struct intel_uncore *uncore = &dev_priv->uncore; unsigned long ggtt_end = ggtt->vm.total; unsigned long mappable_base, mappable_size, mappable_end; @@ -241,16 +248,18 @@ int intel_vgt_balloon(struct i915_ggtt *ggtt) mappable_end = mappable_base + mappable_size; unmappable_end = unmappable_base + unmappable_size; - DRM_INFO("VGT ballooning configuration:\n"); - DRM_INFO("Mappable graphic memory: base 0x%lx size %ldKiB\n", + drm_info(&dev_priv->drm, "VGT ballooning configuration:\n"); + drm_info(&dev_priv->drm, + "Mappable graphic memory: base 0x%lx size %ldKiB\n", mappable_base, mappable_size / 1024); - DRM_INFO("Unmappable graphic memory: base 0x%lx size %ldKiB\n", + drm_info(&dev_priv->drm, + "Unmappable graphic memory: base 0x%lx size %ldKiB\n", unmappable_base, unmappable_size / 1024); if (mappable_end > ggtt->mappable_end || unmappable_base < ggtt->mappable_end || unmappable_end > ggtt_end) { - DRM_ERROR("Invalid ballooning configuration!\n"); + drm_err(&dev_priv->drm, "Invalid ballooning configuration!\n"); return -EINVAL; } @@ -287,7 +296,7 @@ int intel_vgt_balloon(struct i915_ggtt *ggtt) goto err_below_mappable; } - DRM_INFO("VGT balloon successfully\n"); + drm_info(&dev_priv->drm, "VGT balloon successfully\n"); return 0; err_below_mappable: @@ -297,6 +306,6 @@ int intel_vgt_balloon(struct i915_ggtt *ggtt) err_upon_mappable: vgt_deballoon_space(ggtt, &bl_info.space[2]); err: - DRM_ERROR("VGT balloon fail\n"); + drm_err(&dev_priv->drm, "VGT balloon fail\n"); return ret; } From 5e04eb0147223ccaa7e2f510aec07ca06b378f6a Mon Sep 17 00:00:00 2001 From: Wambui Karuga Date: Thu, 9 Jan 2020 12:06:43 +0300 Subject: [PATCH 0070/1537] drm/i915: conversion to new logging macros in i915/intel_csr.c Replace the use of printk and struct device based logging macros with the new struct drm_device based logging macros in i915/intel_csr.c Signed-off-by: Wambui Karuga Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/0ea8e0f39013a73ed66052893a8f8abf8cc23ba6.1578560355.git.wambui.karugax@gmail.com --- drivers/gpu/drm/i915/intel_csr.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index 09870a31b4f0..85e41db7dc0e 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c @@ -298,12 +298,14 @@ void intel_csr_load_program(struct drm_i915_private *dev_priv) u32 i, fw_size; if (!HAS_CSR(dev_priv)) { - DRM_ERROR("No CSR support available for this platform\n"); + drm_err(&dev_priv->drm, + "No CSR support available for this platform\n"); return; } if (!dev_priv->csr.dmc_payload) { - DRM_ERROR("Tried to program CSR with empty payload\n"); + drm_err(&dev_priv->drm, + "Tried to program CSR with empty payload\n"); return; } @@ -636,16 +638,16 @@ static void csr_load_work_fn(struct work_struct *work) intel_csr_load_program(dev_priv); intel_csr_runtime_pm_put(dev_priv); - DRM_INFO("Finished loading DMC firmware %s (v%u.%u)\n", - dev_priv->csr.fw_path, - CSR_VERSION_MAJOR(csr->version), + drm_info(&dev_priv->drm, + "Finished loading DMC firmware %s (v%u.%u)\n", + dev_priv->csr.fw_path, CSR_VERSION_MAJOR(csr->version), CSR_VERSION_MINOR(csr->version)); } else { - dev_notice(dev_priv->drm.dev, + drm_notice(&dev_priv->drm, "Failed to load DMC firmware %s." " Disabling runtime power management.\n", csr->fw_path); - dev_notice(dev_priv->drm.dev, "DMC firmware homepage: %s", + drm_notice(&dev_priv->drm, "DMC firmware homepage: %s", INTEL_UC_FIRMWARE_URL); } @@ -712,7 +714,8 @@ void intel_csr_ucode_init(struct drm_i915_private *dev_priv) if (i915_modparams.dmc_firmware_path) { if (strlen(i915_modparams.dmc_firmware_path) == 0) { csr->fw_path = NULL; - DRM_INFO("Disabling CSR firmware and runtime PM\n"); + drm_info(&dev_priv->drm, + "Disabling CSR firmware and runtime PM\n"); return; } @@ -722,11 +725,12 @@ void intel_csr_ucode_init(struct drm_i915_private *dev_priv) } if (csr->fw_path == NULL) { - DRM_DEBUG_KMS("No known CSR firmware for platform, disabling runtime PM\n"); + drm_dbg_kms(&dev_priv->drm, + "No known CSR firmware for platform, disabling runtime PM\n"); return; } - DRM_DEBUG_KMS("Loading %s\n", csr->fw_path); + drm_dbg_kms(&dev_priv->drm, "Loading %s\n", csr->fw_path); schedule_work(&dev_priv->csr.work); } From 68b3271729f53d89c59875c79013b230b1ff4f36 Mon Sep 17 00:00:00 2001 From: Wambui Karuga Date: Thu, 9 Jan 2020 12:06:44 +0300 Subject: [PATCH 0071/1537] drm/i915: conversion to new logging macros in i915/intel_device_info.c This replaces the printk and struct device based logging macros with the new struct drm_device style based logging macros i915/intel_device_info.c. Signed-off-by: Wambui Karuga Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/e404429ff2a5e5080867f577beccd7b578a671cd.1578560355.git.wambui.karugax@gmail.com --- drivers/gpu/drm/i915/intel_device_info.c | 25 +++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c index 6670a0763be2..fcdacd6d4aa5 100644 --- a/drivers/gpu/drm/i915/intel_device_info.c +++ b/drivers/gpu/drm/i915/intel_device_info.c @@ -974,10 +974,11 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv) sfuse_strap & SFUSE_STRAP_DISPLAY_DISABLED || (HAS_PCH_CPT(dev_priv) && !(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) { - DRM_INFO("Display fused off, disabling\n"); + drm_info(&dev_priv->drm, + "Display fused off, disabling\n"); info->pipe_mask = 0; } else if (fuse_strap & IVB_PIPE_C_DISABLE) { - DRM_INFO("PipeC fused off\n"); + drm_info(&dev_priv->drm, "PipeC fused off\n"); info->pipe_mask &= ~BIT(PIPE_C); } } else if (HAS_DISPLAY(dev_priv) && INTEL_GEN(dev_priv) >= 9) { @@ -1000,8 +1001,9 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv) * in the mask. */ if (enabled_mask == 0 || !is_power_of_2(enabled_mask + 1)) - DRM_ERROR("invalid pipe fuse configuration: enabled_mask=0x%x\n", - enabled_mask); + drm_err(&dev_priv->drm, + "invalid pipe fuse configuration: enabled_mask=0x%x\n", + enabled_mask); else info->pipe_mask = enabled_mask; @@ -1036,7 +1038,8 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv) gen12_sseu_info_init(dev_priv); if (IS_GEN(dev_priv, 6) && intel_vtd_active()) { - DRM_INFO("Disabling ppGTT for VT-d support\n"); + drm_info(&dev_priv->drm, + "Disabling ppGTT for VT-d support\n"); info->ppgtt_type = INTEL_PPGTT_NONE; } @@ -1084,7 +1087,7 @@ void intel_device_info_init_mmio(struct drm_i915_private *dev_priv) if (!(BIT(i) & vdbox_mask)) { info->engine_mask &= ~BIT(_VCS(i)); - DRM_DEBUG_DRIVER("vcs%u fused off\n", i); + drm_dbg(&dev_priv->drm, "vcs%u fused off\n", i); continue; } @@ -1096,8 +1099,8 @@ void intel_device_info_init_mmio(struct drm_i915_private *dev_priv) if (INTEL_GEN(dev_priv) >= 12 || logical_vdbox++ % 2 == 0) RUNTIME_INFO(dev_priv)->vdbox_sfc_access |= BIT(i); } - DRM_DEBUG_DRIVER("vdbox enable: %04x, instances: %04lx\n", - vdbox_mask, VDBOX_MASK(dev_priv)); + drm_dbg(&dev_priv->drm, "vdbox enable: %04x, instances: %04lx\n", + vdbox_mask, VDBOX_MASK(dev_priv)); GEM_BUG_ON(vdbox_mask != VDBOX_MASK(dev_priv)); for (i = 0; i < I915_MAX_VECS; i++) { @@ -1108,10 +1111,10 @@ void intel_device_info_init_mmio(struct drm_i915_private *dev_priv) if (!(BIT(i) & vebox_mask)) { info->engine_mask &= ~BIT(_VECS(i)); - DRM_DEBUG_DRIVER("vecs%u fused off\n", i); + drm_dbg(&dev_priv->drm, "vecs%u fused off\n", i); } } - DRM_DEBUG_DRIVER("vebox enable: %04x, instances: %04lx\n", - vebox_mask, VEBOX_MASK(dev_priv)); + drm_dbg(&dev_priv->drm, "vebox enable: %04x, instances: %04lx\n", + vebox_mask, VEBOX_MASK(dev_priv)); GEM_BUG_ON(vebox_mask != VEBOX_MASK(dev_priv)); } From fd6735fc630cf1d4a38351be81d6b87e4a4204f8 Mon Sep 17 00:00:00 2001 From: Wambui Karuga Date: Thu, 9 Jan 2020 12:06:45 +0300 Subject: [PATCH 0072/1537] drm/i915: convert to new logging macros in i915/intel_gvt.c This converts the use of printk based logging macros in i915/intel_gvt.c with the new struct drm_device based logging macros. Signed-off-by: Wambui Karuga Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/44f3839820a32ed03d73dc56a6ef3581994802c9.1578560355.git.wambui.karugax@gmail.com --- drivers/gpu/drm/i915/intel_gvt.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_gvt.c b/drivers/gpu/drm/i915/intel_gvt.c index 2b6c016387c2..38ebd5562c7c 100644 --- a/drivers/gpu/drm/i915/intel_gvt.c +++ b/drivers/gpu/drm/i915/intel_gvt.c @@ -67,12 +67,13 @@ void intel_gvt_sanitize_options(struct drm_i915_private *dev_priv) return; if (intel_vgpu_active(dev_priv)) { - DRM_INFO("GVT-g is disabled for guest\n"); + drm_info(&dev_priv->drm, "GVT-g is disabled for guest\n"); goto bail; } if (!is_supported_device(dev_priv)) { - DRM_INFO("Unsupported device. GVT-g is disabled\n"); + drm_info(&dev_priv->drm, + "Unsupported device. GVT-g is disabled\n"); goto bail; } @@ -99,18 +100,20 @@ int intel_gvt_init(struct drm_i915_private *dev_priv) return -ENODEV; if (!i915_modparams.enable_gvt) { - DRM_DEBUG_DRIVER("GVT-g is disabled by kernel params\n"); + drm_dbg(&dev_priv->drm, + "GVT-g is disabled by kernel params\n"); return 0; } if (USES_GUC_SUBMISSION(dev_priv)) { - DRM_ERROR("i915 GVT-g loading failed due to Graphics virtualization is not yet supported with GuC submission\n"); + drm_err(&dev_priv->drm, + "i915 GVT-g loading failed due to Graphics virtualization is not yet supported with GuC submission\n"); return -EIO; } ret = intel_gvt_init_device(dev_priv); if (ret) { - DRM_DEBUG_DRIVER("Fail to init GVT device\n"); + drm_dbg(&dev_priv->drm, "Fail to init GVT device\n"); goto bail; } From 89c02493deb93852f4b361aaeae11b80ab8edda0 Mon Sep 17 00:00:00 2001 From: Wambui Karuga Date: Thu, 9 Jan 2020 12:06:46 +0300 Subject: [PATCH 0073/1537] drm/i915: convert to new logging macros in i915/intel_memory_region.c Replace the use of printk based logging macros with the new struct drm_device based logging macro in i915/intel_memory_region.c. Signed-off-by: Wambui Karuga Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1bf4d362e72c619843d44aac96c3561f54e4b23a.1578560355.git.wambui.karugax@gmail.com --- drivers/gpu/drm/i915/intel_memory_region.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c index d0d038b3cd79..6b5e9d88646d 100644 --- a/drivers/gpu/drm/i915/intel_memory_region.c +++ b/drivers/gpu/drm/i915/intel_memory_region.c @@ -265,7 +265,9 @@ int intel_memory_regions_hw_probe(struct drm_i915_private *i915) if (IS_ERR(mem)) { err = PTR_ERR(mem); - DRM_ERROR("Failed to setup region(%d) type=%d\n", err, type); + drm_err(&i915->drm, + "Failed to setup region(%d) type=%d\n", + err, type); goto out_cleanup; } From 94523024363b373584bfb0a8eed9ba194d41b4d5 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 17 Jan 2020 11:32:59 +0000 Subject: [PATCH 0074/1537] drm/i915/gt: Report the currently active execlists request Since commit 22b7a426bbe1 ("drm/i915/execlists: Preempt-to-busy"), we prune the engine->active.requests list prior to preemption, thus removing the trace of the currently executing request. If that request hangs rather than be preempted, we conclude that no active request was on the GPU. Fortunately, this only impacts our debugging, and not our means of hang detection or recovery. v2: Use from to check the current iterator before continuing, and report active as NULL if the current request is already completed. References: 22b7a426bbe1 ("drm/i915/execlists: Preempt-to-busy") Signed-off-by: Chris Wilson Cc: Mika Kuoppala Reviewed-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20200117113259.3023890-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index 06ff7695fa29..2d0ef5fc6748 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -1657,6 +1657,23 @@ intel_engine_find_active_request(struct intel_engine_cs *engine) * we only care about the snapshot of this moment. */ lockdep_assert_held(&engine->active.lock); + + rcu_read_lock(); + request = execlists_active(&engine->execlists); + if (request) { + struct intel_timeline *tl = request->context->timeline; + + list_for_each_entry_from_reverse(request, &tl->requests, link) { + if (i915_request_completed(request)) + break; + + active = request; + } + } + rcu_read_unlock(); + if (active) + return active; + list_for_each_entry(request, &engine->active.requests, sched.link) { if (i915_request_completed(request)) continue; From af6cb95cf641053a3c0a46d5deb736f7e85c44d9 Mon Sep 17 00:00:00 2001 From: Jitao Shi Date: Thu, 16 Jan 2020 10:15:07 +0800 Subject: [PATCH 0075/1537] dt-bindings: display: panel: Add boe tv101wum-n16 panel bindings Add documentation for "boe,tv101wum-n16", "auo,kd101n80-45na", "boe,tv101wum-n53" and "auo,b101uan08.3" panels. Signed-off-by: Jitao Shi Reviewed-by: Sam Ravnborg [dropped Rob from list of maintainers - verified on irc] Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200116021511.22675-2-jitao.shi@mediatek.com --- .../display/panel/boe,tv101wum-nl6.yaml | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/boe,tv101wum-nl6.yaml diff --git a/Documentation/devicetree/bindings/display/panel/boe,tv101wum-nl6.yaml b/Documentation/devicetree/bindings/display/panel/boe,tv101wum-nl6.yaml new file mode 100644 index 000000000000..740213459134 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/boe,tv101wum-nl6.yaml @@ -0,0 +1,80 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/boe,tv101wum-nl6.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: BOE TV101WUM-NL6 DSI Display Panel + +maintainers: + - Thierry Reding + - Sam Ravnborg + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: + enum: + # BOE TV101WUM-NL6 10.1" WUXGA TFT LCD panel + - boe,tv101wum-nl6 + # AUO KD101N80-45NA 10.1" WUXGA TFT LCD panel + - auo,kd101n80-45na + # BOE TV101WUM-N53 10.1" WUXGA TFT LCD panel + - boe,tv101wum-n53 + # AUO B101UAN08.3 10.1" WUXGA TFT LCD panel + - auo,b101uan08.3 + + reg: + description: the virtual channel number of a DSI peripheral + + enable-gpios: + description: a GPIO spec for the enable pin + + pp1800-supply: + description: core voltage supply + + avdd-supply: + description: phandle of the regulator that provides positive voltage + + avee-supply: + description: phandle of the regulator that provides negative voltage + + backlight: + description: phandle of the backlight device attached to the panel + + port: true + +required: + - compatible + - reg + - enable-gpios + - pp1800-supply + - avdd-supply + - avee-supply + +additionalProperties: false + +examples: + - | + dsi { + #address-cells = <1>; + #size-cells = <0>; + panel@0 { + compatible = "boe,tv101wum-nl6"; + reg = <0>; + enable-gpios = <&pio 45 0>; + avdd-supply = <&ppvarn_lcd>; + avee-supply = <&ppvarp_lcd>; + pp1800-supply = <&pp1800_lcd>; + backlight = <&backlight_lcd0>; + status = "okay"; + port { + panel_in: endpoint { + remote-endpoint = <&dsi_out>; + }; + }; + }; + }; + +... From a869b9db7adf3bddb56521f8c24e3eacddaecbff Mon Sep 17 00:00:00 2001 From: Jitao Shi Date: Thu, 16 Jan 2020 10:15:08 +0800 Subject: [PATCH 0076/1537] drm/panel: support for boe tv101wum-nl6 wuxga dsi video mode panel Add driver for BOE tv101wum-nl6 panel is a 10.1" 1200x1920 panel. Signed-off-by: Jitao Shi Reviewed-by: Sam Ravnborg Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200116021511.22675-3-jitao.shi@mediatek.com --- drivers/gpu/drm/panel/Kconfig | 9 + drivers/gpu/drm/panel/Makefile | 1 + .../gpu/drm/panel/panel-boe-tv101wum-nl6.c | 693 ++++++++++++++++++ 3 files changed, 703 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index ae44ac2ec106..ca727c233a9a 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -29,6 +29,15 @@ config DRM_PANEL_BOE_HIMAX8279D 24 bit RGB per pixel. It provides a MIPI DSI interface to the host and has a built-in LED backlight. +config DRM_PANEL_BOE_TV101WUM_NL6 + tristate "BOE TV101WUM 1200x1920 panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to support for BOE TV101WUM WUXGA PANEL + DSI Video Mode panel + config DRM_PANEL_LVDS tristate "Generic LVDS panel driver" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 7c4d3c581fd4..a659ce403d0e 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_DRM_PANEL_ARM_VERSATILE) += panel-arm-versatile.o obj-$(CONFIG_DRM_PANEL_BOE_HIMAX8279D) += panel-boe-himax8279d.o +obj-$(CONFIG_DRM_PANEL_BOE_TV101WUM_NL6) += panel-boe-tv101wum-nl6.o obj-$(CONFIG_DRM_PANEL_LVDS) += panel-lvds.o obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += panel-feiyang-fy07024di26a30d.o diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c new file mode 100644 index 000000000000..51fde588adc1 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c @@ -0,0 +1,693 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Jitao Shi + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include