Some drivers, eg. mtk_drm and msm_drm, rely on the panel to set the orientation. Panel calls drm_connector_set_panel_orientation() to create orientation property and sets the value. However, connector properties can't be created after drm_dev_register() is called. The goal is to separate the orientation property creation, so drm drivers can create it earlier before drm_dev_register().
After this series, drm_connector_set_panel_orientation() works like before. It won't affect existing callers of drm_connector_set_panel_orientation(). The only difference is that some drm drivers can call drm_connector_init_panel_orientation_property() earlier.
Hsin-Yi Wang (4): gpu: drm: separate panel orientation property creating and value setting drm/mediatek: init panel orientation property drm/msm: init panel orientation property arm64: dts: mt8183: Add panel rotation
.../arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 1 + drivers/gpu/drm/drm_connector.c | 58 ++++++++++++++----- drivers/gpu/drm/mediatek/mtk_dsi.c | 7 +++ drivers/gpu/drm/msm/dsi/dsi_manager.c | 4 ++ include/drm/drm_connector.h | 2 + 5 files changed, 59 insertions(+), 13 deletions(-)
drm_dev_register() sets connector->registration_state to DRM_CONNECTOR_REGISTERED and dev->registered to true. If drm_connector_set_panel_orientation() is first called after drm_dev_register(), it will fail several checks and results in following warning.
Add a function to create panel orientation property and set default value to UNKNOWN, so drivers can call this function to init the property earlier , and let the panel set the real value later.
[ 4.480976] ------------[ cut here ]------------ [ 4.485603] WARNING: CPU: 5 PID: 369 at drivers/gpu/drm/drm_mode_object.c:45 __drm_mode_object_add+0xb4/0xbc <snip> [ 4.609772] Call trace: [ 4.612208] __drm_mode_object_add+0xb4/0xbc [ 4.616466] drm_mode_object_add+0x20/0x2c [ 4.620552] drm_property_create+0xdc/0x174 [ 4.624723] drm_property_create_enum+0x34/0x98 [ 4.629241] drm_connector_set_panel_orientation+0x64/0xa0 [ 4.634716] boe_panel_get_modes+0x88/0xd8 [ 4.638802] drm_panel_get_modes+0x2c/0x48 [ 4.642887] panel_bridge_get_modes+0x1c/0x28 [ 4.647233] drm_bridge_connector_get_modes+0xa0/0xd4 [ 4.652273] drm_helper_probe_single_connector_modes+0x218/0x700 [ 4.658266] drm_mode_getconnector+0x1b4/0x45c [ 4.662699] drm_ioctl_kernel+0xac/0x128 [ 4.666611] drm_ioctl+0x268/0x410 [ 4.670002] drm_compat_ioctl+0xdc/0xf0 [ 4.673829] __arm64_compat_sys_ioctl+0xc8/0x100 [ 4.678436] el0_svc_common+0xf4/0x1c0 [ 4.682174] do_el0_svc_compat+0x28/0x3c [ 4.686088] el0_svc_compat+0x10/0x1c [ 4.689738] el0_sync_compat_handler+0xa8/0xcc [ 4.694171] el0_sync_compat+0x178/0x180 [ 4.698082] ---[ end trace b4f2db9d9c88610b ]--- [ 4.702721] ------------[ cut here ]------------ [ 4.707329] WARNING: CPU: 5 PID: 369 at drivers/gpu/drm/drm_mode_object.c:243 drm_object_attach_property+0x48/0xb8 <snip> [ 4.833830] Call trace: [ 4.836266] drm_object_attach_property+0x48/0xb8 [ 4.840958] drm_connector_set_panel_orientation+0x84/0xa0 [ 4.846432] boe_panel_get_modes+0x88/0xd8 [ 4.850516] drm_panel_get_modes+0x2c/0x48 [ 4.854600] panel_bridge_get_modes+0x1c/0x28 [ 4.858946] drm_bridge_connector_get_modes+0xa0/0xd4 [ 4.863984] drm_helper_probe_single_connector_modes+0x218/0x700 [ 4.869978] drm_mode_getconnector+0x1b4/0x45c [ 4.874410] drm_ioctl_kernel+0xac/0x128 [ 4.878320] drm_ioctl+0x268/0x410 [ 4.881711] drm_compat_ioctl+0xdc/0xf0 [ 4.885536] __arm64_compat_sys_ioctl+0xc8/0x100 [ 4.890142] el0_svc_common+0xf4/0x1c0 [ 4.893879] do_el0_svc_compat+0x28/0x3c [ 4.897791] el0_svc_compat+0x10/0x1c [ 4.901441] el0_sync_compat_handler+0xa8/0xcc [ 4.905873] el0_sync_compat+0x178/0x180 [ 4.909783] ---[ end trace b4f2db9d9c88610c ]---
Signed-off-by: Hsin-Yi Wang hsinyi@chromium.org Reviewed-by: Sean Paul seanpaul@chromium.org --- v9->v10: rebase to latest linux-next. v9: https://patchwork.kernel.org/project/linux-mediatek/patch/20220318074825.335... v8: https://patchwork.kernel.org/project/linux-mediatek/patch/20220208084234.168... v7: https://patchwork.kernel.org/project/linux-mediatek/patch/20220208073714.154... --- drivers/gpu/drm/drm_connector.c | 58 +++++++++++++++++++++++++-------- include/drm/drm_connector.h | 2 ++ 2 files changed, 47 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 1c48d162c77e..d68cc78f6684 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1252,7 +1252,7 @@ static const struct drm_prop_enum_list dp_colorspaces[] = { * INPUT_PROP_DIRECT) will still map 1:1 to the actual LCD panel * 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 + * touchscreen input coordinates. This property value is set by calling * drm_connector_set_panel_orientation() or * drm_connector_set_panel_orientation_with_quirk() * @@ -2310,8 +2310,8 @@ EXPORT_SYMBOL(drm_connector_set_vrr_capable_property); * @connector: connector for which to set the panel-orientation property. * @panel_orientation: drm_panel_orientation value to set * - * This function sets the connector's panel_orientation and attaches - * a "panel orientation" property to the connector. + * This function sets the connector's panel_orientation value. If the property + * doesn't exist, it will try to create one. * * 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 @@ -2343,18 +2343,13 @@ int drm_connector_set_panel_orientation(
prop = dev->mode_config.panel_orientation_property; if (!prop) { - prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, - "panel orientation", - drm_panel_orientation_enum_list, - ARRAY_SIZE(drm_panel_orientation_enum_list)); - if (!prop) + if (drm_connector_init_panel_orientation_property(connector) < 0) return -ENOMEM; - - dev->mode_config.panel_orientation_property = prop; + prop = dev->mode_config.panel_orientation_property; }
- drm_object_attach_property(&connector->base, prop, - info->panel_orientation); + drm_object_property_set_value(&connector->base, prop, + info->panel_orientation); return 0; } EXPORT_SYMBOL(drm_connector_set_panel_orientation); @@ -2362,7 +2357,7 @@ EXPORT_SYMBOL(drm_connector_set_panel_orientation); /** * drm_connector_set_panel_orientation_with_quirk - set the * connector's panel_orientation after checking for quirks - * @connector: connector for which to init the panel-orientation property. + * @connector: connector for which to set 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 @@ -2389,6 +2384,43 @@ int drm_connector_set_panel_orientation_with_quirk( } EXPORT_SYMBOL(drm_connector_set_panel_orientation_with_quirk);
+/** + * drm_connector_init_panel_orientation_property - + * create the connector's panel orientation property + * + * This function attaches a "panel orientation" property to the connector + * and initializes its value to DRM_MODE_PANEL_ORIENTATION_UNKNOWN. + * + * The value of the property can be set by drm_connector_set_panel_orientation() + * or drm_connector_set_panel_orientation_with_quirk() later. + * + * Returns: + * Zero on success, negative errno on failure. + */ +int drm_connector_init_panel_orientation_property( + struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct drm_property *prop; + + if(dev->mode_config.panel_orientation_property) + return 0; + + prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, + "panel orientation", + drm_panel_orientation_enum_list, + ARRAY_SIZE(drm_panel_orientation_enum_list)); + if (!prop) + return -ENOMEM; + + dev->mode_config.panel_orientation_property = prop; + drm_object_attach_property(&connector->base, prop, + DRM_MODE_PANEL_ORIENTATION_UNKNOWN); + + return 0; +} +EXPORT_SYMBOL(drm_connector_init_panel_orientation_property); + static const struct drm_prop_enum_list privacy_screen_enum[] = { { PRIVACY_SCREEN_DISABLED, "Disabled" }, { PRIVACY_SCREEN_ENABLED, "Enabled" }, diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 3ac4bf87f257..f0681091c617 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1802,6 +1802,8 @@ 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_init_panel_orientation_property( + struct drm_connector *connector); int drm_connector_attach_max_bpc_property(struct drm_connector *connector, int min, int max); void drm_connector_create_privacy_screen_properties(struct drm_connector *conn);
Hi,
On 5/30/22 10:19, Hsin-Yi Wang wrote:
drm_dev_register() sets connector->registration_state to DRM_CONNECTOR_REGISTERED and dev->registered to true. If drm_connector_set_panel_orientation() is first called after drm_dev_register(), it will fail several checks and results in following warning.
Add a function to create panel orientation property and set default value to UNKNOWN, so drivers can call this function to init the property earlier , and let the panel set the real value later.
[ 4.480976] ------------[ cut here ]------------ [ 4.485603] WARNING: CPU: 5 PID: 369 at drivers/gpu/drm/drm_mode_object.c:45 __drm_mode_object_add+0xb4/0xbc
<snip> [ 4.609772] Call trace: [ 4.612208] __drm_mode_object_add+0xb4/0xbc [ 4.616466] drm_mode_object_add+0x20/0x2c [ 4.620552] drm_property_create+0xdc/0x174 [ 4.624723] drm_property_create_enum+0x34/0x98 [ 4.629241] drm_connector_set_panel_orientation+0x64/0xa0 [ 4.634716] boe_panel_get_modes+0x88/0xd8 [ 4.638802] drm_panel_get_modes+0x2c/0x48 [ 4.642887] panel_bridge_get_modes+0x1c/0x28 [ 4.647233] drm_bridge_connector_get_modes+0xa0/0xd4 [ 4.652273] drm_helper_probe_single_connector_modes+0x218/0x700 [ 4.658266] drm_mode_getconnector+0x1b4/0x45c [ 4.662699] drm_ioctl_kernel+0xac/0x128 [ 4.666611] drm_ioctl+0x268/0x410 [ 4.670002] drm_compat_ioctl+0xdc/0xf0 [ 4.673829] __arm64_compat_sys_ioctl+0xc8/0x100 [ 4.678436] el0_svc_common+0xf4/0x1c0 [ 4.682174] do_el0_svc_compat+0x28/0x3c [ 4.686088] el0_svc_compat+0x10/0x1c [ 4.689738] el0_sync_compat_handler+0xa8/0xcc [ 4.694171] el0_sync_compat+0x178/0x180 [ 4.698082] ---[ end trace b4f2db9d9c88610b ]--- [ 4.702721] ------------[ cut here ]------------ [ 4.707329] WARNING: CPU: 5 PID: 369 at drivers/gpu/drm/drm_mode_object.c:243 drm_object_attach_property+0x48/0xb8 <snip> [ 4.833830] Call trace: [ 4.836266] drm_object_attach_property+0x48/0xb8 [ 4.840958] drm_connector_set_panel_orientation+0x84/0xa0 [ 4.846432] boe_panel_get_modes+0x88/0xd8 [ 4.850516] drm_panel_get_modes+0x2c/0x48 [ 4.854600] panel_bridge_get_modes+0x1c/0x28 [ 4.858946] drm_bridge_connector_get_modes+0xa0/0xd4 [ 4.863984] drm_helper_probe_single_connector_modes+0x218/0x700 [ 4.869978] drm_mode_getconnector+0x1b4/0x45c [ 4.874410] drm_ioctl_kernel+0xac/0x128 [ 4.878320] drm_ioctl+0x268/0x410 [ 4.881711] drm_compat_ioctl+0xdc/0xf0 [ 4.885536] __arm64_compat_sys_ioctl+0xc8/0x100 [ 4.890142] el0_svc_common+0xf4/0x1c0 [ 4.893879] do_el0_svc_compat+0x28/0x3c [ 4.897791] el0_svc_compat+0x10/0x1c [ 4.901441] el0_sync_compat_handler+0xa8/0xcc [ 4.905873] el0_sync_compat+0x178/0x180 [ 4.909783] ---[ end trace b4f2db9d9c88610c ]---
Signed-off-by: Hsin-Yi Wang hsinyi@chromium.org Reviewed-by: Sean Paul seanpaul@chromium.org
v9->v10: rebase to latest linux-next. v9: https://patchwork.kernel.org/project/linux-mediatek/patch/20220318074825.335... v8: https://patchwork.kernel.org/project/linux-mediatek/patch/20220208084234.168... v7: https://patchwork.kernel.org/project/linux-mediatek/patch/20220208073714.154...
drivers/gpu/drm/drm_connector.c | 58 +++++++++++++++++++++++++-------- include/drm/drm_connector.h | 2 ++ 2 files changed, 47 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 1c48d162c77e..d68cc78f6684 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1252,7 +1252,7 @@ static const struct drm_prop_enum_list dp_colorspaces[] = {
- INPUT_PROP_DIRECT) will still map 1:1 to the actual LCD panel
- 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
- touchscreen input coordinates. This property value is set by calling
- drm_connector_set_panel_orientation() or
- drm_connector_set_panel_orientation_with_quirk()
@@ -2310,8 +2310,8 @@ EXPORT_SYMBOL(drm_connector_set_vrr_capable_property);
- @connector: connector for which to set the panel-orientation property.
- @panel_orientation: drm_panel_orientation value to set
- This function sets the connector's panel_orientation and attaches
- a "panel orientation" property to the connector.
- This function sets the connector's panel_orientation value. If the property
- doesn't exist, it will try to create one.
- 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
@@ -2343,18 +2343,13 @@ int drm_connector_set_panel_orientation(
prop = dev->mode_config.panel_orientation_property; if (!prop) {
prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
"panel orientation",
drm_panel_orientation_enum_list,
ARRAY_SIZE(drm_panel_orientation_enum_list));
if (!prop)
if (drm_connector_init_panel_orientation_property(connector) < 0) return -ENOMEM;
dev->mode_config.panel_orientation_property = prop;
}prop = dev->mode_config.panel_orientation_property;
- drm_object_attach_property(&connector->base, prop,
info->panel_orientation);
- drm_object_property_set_value(&connector->base, prop,
return 0;info->panel_orientation);
} EXPORT_SYMBOL(drm_connector_set_panel_orientation); @@ -2362,7 +2357,7 @@ EXPORT_SYMBOL(drm_connector_set_panel_orientation); /**
- drm_connector_set_panel_orientation_with_quirk - set the
- connector's panel_orientation after checking for quirks
- @connector: connector for which to init the panel-orientation property.
- @connector: connector for which to set 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
@@ -2389,6 +2384,43 @@ int drm_connector_set_panel_orientation_with_quirk( } EXPORT_SYMBOL(drm_connector_set_panel_orientation_with_quirk);
+/**
- drm_connector_init_panel_orientation_property -
- create the connector's panel orientation property
- This function attaches a "panel orientation" property to the connector
- and initializes its value to DRM_MODE_PANEL_ORIENTATION_UNKNOWN.
- The value of the property can be set by drm_connector_set_panel_orientation()
- or drm_connector_set_panel_orientation_with_quirk() later.
- Returns:
- Zero on success, negative errno on failure.
- */
+int drm_connector_init_panel_orientation_property(
- struct drm_connector *connector)
+{
- struct drm_device *dev = connector->dev;
- struct drm_property *prop;
- if(dev->mode_config.panel_orientation_property)
return 0;
- prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
"panel orientation",
drm_panel_orientation_enum_list,
ARRAY_SIZE(drm_panel_orientation_enum_list));
- if (!prop)
return -ENOMEM;
- dev->mode_config.panel_orientation_property = prop;
- drm_object_attach_property(&connector->base, prop,
DRM_MODE_PANEL_ORIENTATION_UNKNOWN);
DRM_MODE_PANEL_ORIENTATION_UNKNOWN is -1 which is not a valid value for an enum. IOW when the panel-orientation is DRM_MODE_PANEL_ORIENTATION_UNKNOWN then the property should not be created on the drm-connector object at all.
Which brings us back to what I said in reply to the coverletter, it seems that you have a probe ordering problem here; and fixing that issue would make this patch-set unnecessary.
Regards,
Hans
- return 0;
+} +EXPORT_SYMBOL(drm_connector_init_panel_orientation_property);
static const struct drm_prop_enum_list privacy_screen_enum[] = { { PRIVACY_SCREEN_DISABLED, "Disabled" }, { PRIVACY_SCREEN_ENABLED, "Enabled" }, diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 3ac4bf87f257..f0681091c617 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1802,6 +1802,8 @@ 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_init_panel_orientation_property(
- struct drm_connector *connector);
int drm_connector_attach_max_bpc_property(struct drm_connector *connector, int min, int max); void drm_connector_create_privacy_screen_properties(struct drm_connector *conn);
Hi,
On 5/30/22 10:57, Hans de Goede wrote:
Hi,
On 5/30/22 10:19, Hsin-Yi Wang wrote:
drm_dev_register() sets connector->registration_state to DRM_CONNECTOR_REGISTERED and dev->registered to true. If drm_connector_set_panel_orientation() is first called after drm_dev_register(), it will fail several checks and results in following warning.
Add a function to create panel orientation property and set default value to UNKNOWN, so drivers can call this function to init the property earlier , and let the panel set the real value later.
[ 4.480976] ------------[ cut here ]------------ [ 4.485603] WARNING: CPU: 5 PID: 369 at drivers/gpu/drm/drm_mode_object.c:45 __drm_mode_object_add+0xb4/0xbc
<snip> [ 4.609772] Call trace: [ 4.612208] __drm_mode_object_add+0xb4/0xbc [ 4.616466] drm_mode_object_add+0x20/0x2c [ 4.620552] drm_property_create+0xdc/0x174 [ 4.624723] drm_property_create_enum+0x34/0x98 [ 4.629241] drm_connector_set_panel_orientation+0x64/0xa0 [ 4.634716] boe_panel_get_modes+0x88/0xd8 [ 4.638802] drm_panel_get_modes+0x2c/0x48 [ 4.642887] panel_bridge_get_modes+0x1c/0x28 [ 4.647233] drm_bridge_connector_get_modes+0xa0/0xd4 [ 4.652273] drm_helper_probe_single_connector_modes+0x218/0x700 [ 4.658266] drm_mode_getconnector+0x1b4/0x45c [ 4.662699] drm_ioctl_kernel+0xac/0x128 [ 4.666611] drm_ioctl+0x268/0x410 [ 4.670002] drm_compat_ioctl+0xdc/0xf0 [ 4.673829] __arm64_compat_sys_ioctl+0xc8/0x100 [ 4.678436] el0_svc_common+0xf4/0x1c0 [ 4.682174] do_el0_svc_compat+0x28/0x3c [ 4.686088] el0_svc_compat+0x10/0x1c [ 4.689738] el0_sync_compat_handler+0xa8/0xcc [ 4.694171] el0_sync_compat+0x178/0x180 [ 4.698082] ---[ end trace b4f2db9d9c88610b ]--- [ 4.702721] ------------[ cut here ]------------ [ 4.707329] WARNING: CPU: 5 PID: 369 at drivers/gpu/drm/drm_mode_object.c:243 drm_object_attach_property+0x48/0xb8 <snip> [ 4.833830] Call trace: [ 4.836266] drm_object_attach_property+0x48/0xb8 [ 4.840958] drm_connector_set_panel_orientation+0x84/0xa0 [ 4.846432] boe_panel_get_modes+0x88/0xd8 [ 4.850516] drm_panel_get_modes+0x2c/0x48 [ 4.854600] panel_bridge_get_modes+0x1c/0x28 [ 4.858946] drm_bridge_connector_get_modes+0xa0/0xd4 [ 4.863984] drm_helper_probe_single_connector_modes+0x218/0x700 [ 4.869978] drm_mode_getconnector+0x1b4/0x45c [ 4.874410] drm_ioctl_kernel+0xac/0x128 [ 4.878320] drm_ioctl+0x268/0x410 [ 4.881711] drm_compat_ioctl+0xdc/0xf0 [ 4.885536] __arm64_compat_sys_ioctl+0xc8/0x100 [ 4.890142] el0_svc_common+0xf4/0x1c0 [ 4.893879] do_el0_svc_compat+0x28/0x3c [ 4.897791] el0_svc_compat+0x10/0x1c [ 4.901441] el0_sync_compat_handler+0xa8/0xcc [ 4.905873] el0_sync_compat+0x178/0x180 [ 4.909783] ---[ end trace b4f2db9d9c88610c ]---
Signed-off-by: Hsin-Yi Wang hsinyi@chromium.org Reviewed-by: Sean Paul seanpaul@chromium.org
v9->v10: rebase to latest linux-next. v9: https://patchwork.kernel.org/project/linux-mediatek/patch/20220318074825.335... v8: https://patchwork.kernel.org/project/linux-mediatek/patch/20220208084234.168... v7: https://patchwork.kernel.org/project/linux-mediatek/patch/20220208073714.154...
drivers/gpu/drm/drm_connector.c | 58 +++++++++++++++++++++++++-------- include/drm/drm_connector.h | 2 ++ 2 files changed, 47 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 1c48d162c77e..d68cc78f6684 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1252,7 +1252,7 @@ static const struct drm_prop_enum_list dp_colorspaces[] = {
- INPUT_PROP_DIRECT) will still map 1:1 to the actual LCD panel
- 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
- touchscreen input coordinates. This property value is set by calling
- drm_connector_set_panel_orientation() or
- drm_connector_set_panel_orientation_with_quirk()
@@ -2310,8 +2310,8 @@ EXPORT_SYMBOL(drm_connector_set_vrr_capable_property);
- @connector: connector for which to set the panel-orientation property.
- @panel_orientation: drm_panel_orientation value to set
- This function sets the connector's panel_orientation and attaches
- a "panel orientation" property to the connector.
- This function sets the connector's panel_orientation value. If the property
- doesn't exist, it will try to create one.
- 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
@@ -2343,18 +2343,13 @@ int drm_connector_set_panel_orientation(
prop = dev->mode_config.panel_orientation_property; if (!prop) {
prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
"panel orientation",
drm_panel_orientation_enum_list,
ARRAY_SIZE(drm_panel_orientation_enum_list));
if (!prop)
if (drm_connector_init_panel_orientation_property(connector) < 0) return -ENOMEM;
dev->mode_config.panel_orientation_property = prop;
}prop = dev->mode_config.panel_orientation_property;
- drm_object_attach_property(&connector->base, prop,
info->panel_orientation);
- drm_object_property_set_value(&connector->base, prop,
return 0;info->panel_orientation);
} EXPORT_SYMBOL(drm_connector_set_panel_orientation); @@ -2362,7 +2357,7 @@ EXPORT_SYMBOL(drm_connector_set_panel_orientation); /**
- drm_connector_set_panel_orientation_with_quirk - set the
- connector's panel_orientation after checking for quirks
- @connector: connector for which to init the panel-orientation property.
- @connector: connector for which to set 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
@@ -2389,6 +2384,43 @@ int drm_connector_set_panel_orientation_with_quirk( } EXPORT_SYMBOL(drm_connector_set_panel_orientation_with_quirk);
+/**
- drm_connector_init_panel_orientation_property -
- create the connector's panel orientation property
- This function attaches a "panel orientation" property to the connector
- and initializes its value to DRM_MODE_PANEL_ORIENTATION_UNKNOWN.
- The value of the property can be set by drm_connector_set_panel_orientation()
- or drm_connector_set_panel_orientation_with_quirk() later.
- Returns:
- Zero on success, negative errno on failure.
- */
+int drm_connector_init_panel_orientation_property(
- struct drm_connector *connector)
+{
- struct drm_device *dev = connector->dev;
- struct drm_property *prop;
- if(dev->mode_config.panel_orientation_property)
return 0;
- prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
"panel orientation",
drm_panel_orientation_enum_list,
ARRAY_SIZE(drm_panel_orientation_enum_list));
- if (!prop)
return -ENOMEM;
- dev->mode_config.panel_orientation_property = prop;
- drm_object_attach_property(&connector->base, prop,
DRM_MODE_PANEL_ORIENTATION_UNKNOWN);
DRM_MODE_PANEL_ORIENTATION_UNKNOWN is -1 which is not a valid value for an enum. IOW when the panel-orientation is DRM_MODE_PANEL_ORIENTATION_UNKNOWN then the property should not be created on the drm-connector object at all.
p.s. note that the original drm_connector_set_panel_orientation() avoids ever creating the property when the orientation is unknown because of this bit of code near the top of the function:
/* Don't attach the property if the orientation is unknown */ if (panel_orientation == DRM_MODE_PANEL_ORIENTATION_UNKNOWN) return 0;
Which brings us back to what I said in reply to the coverletter, it seems that you have a probe ordering problem here; and fixing that issue would make this patch-set unnecessary.
Regards,
Hans
- return 0;
+} +EXPORT_SYMBOL(drm_connector_init_panel_orientation_property);
static const struct drm_prop_enum_list privacy_screen_enum[] = { { PRIVACY_SCREEN_DISABLED, "Disabled" }, { PRIVACY_SCREEN_ENABLED, "Enabled" }, diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 3ac4bf87f257..f0681091c617 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1802,6 +1802,8 @@ 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_init_panel_orientation_property(
- struct drm_connector *connector);
int drm_connector_attach_max_bpc_property(struct drm_connector *connector, int min, int max); void drm_connector_create_privacy_screen_properties(struct drm_connector *conn);
Init panel orientation property after connector is initialized. Let the panel driver decides the orientation value later.
Signed-off-by: Hsin-Yi Wang hsinyi@chromium.org Acked-by: Chun-Kuang Hu chunkuang.hu@kernel.org --- drivers/gpu/drm/mediatek/mtk_dsi.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index d9f10a33e6fa..3db44d9b161a 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -822,6 +822,13 @@ static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi) ret = PTR_ERR(dsi->connector); goto err_cleanup_encoder; } + + ret = drm_connector_init_panel_orientation_property(dsi->connector); + if (ret) { + DRM_ERROR("Unable to init panel orientation\n"); + goto err_cleanup_encoder; + } + drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
return 0;
Init panel orientation property after connector is initialized. Let the panel driver decides the orientation value later.
Signed-off-by: Hsin-Yi Wang hsinyi@chromium.org --- drivers/gpu/drm/msm/dsi/dsi_manager.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index cb84d185d73a..16ad3d8fab4d 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -669,6 +669,10 @@ struct drm_connector *msm_dsi_manager_connector_init(u8 id) connector->interlace_allowed = 0; connector->doublescan_allowed = 0;
+ ret = drm_connector_init_panel_orientation_property(connector); + if (ret) + goto fail; + drm_connector_attach_encoder(connector, msm_dsi->encoder);
ret = msm_dsi_manager_panel_init(connector, id);
krane, kakadu, and kodama boards have a default panel rotation.
Signed-off-by: Hsin-Yi Wang hsinyi@chromium.org Reviewed-by: Enric Balletbo i Serra enric.balletbo@collabora.com Tested-by: Enric Balletbo i Serra enric.balletbo@collabora.com --- arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi index 8d5bf73a9099..f0dd5a06629d 100644 --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi @@ -276,6 +276,7 @@ panel: panel@0 { avee-supply = <&ppvarp_lcd>; pp1800-supply = <&pp1800_lcd>; backlight = <&backlight_lcd0>; + rotation = <270>; port { panel_in: endpoint { remote-endpoint = <&dsi_out>;
Hi,
On 5/30/22 10:19, Hsin-Yi Wang wrote:
Some drivers, eg. mtk_drm and msm_drm, rely on the panel to set the orientation. Panel calls drm_connector_set_panel_orientation() to create orientation property and sets the value. However, connector properties can't be created after drm_dev_register() is called. The goal is to separate the orientation property creation, so drm drivers can create it earlier before drm_dev_register().
Sorry for jumping in pretty late in the discussion (based on the v10 I seem to have missed this before).
This sounds to me like the real issue here is that drm_dev_register() is getting called too early?
To me it seems sensible to delay calling drm_dev_register() and thus allowing userspace to start detecting available displays + features until after the panel has been probed.
I see a devicetree patch in this series, so I guess that the panel is described in devicetree. Especially in the case of devicetree I would expect the kernel to have enough info to do the right thing and make sure the panel is probed before calling drm_dev_register() ?
Regards,
Hans
After this series, drm_connector_set_panel_orientation() works like before. It won't affect existing callers of drm_connector_set_panel_orientation(). The only difference is that some drm drivers can call drm_connector_init_panel_orientation_property() earlier.
Hsin-Yi Wang (4): gpu: drm: separate panel orientation property creating and value setting drm/mediatek: init panel orientation property drm/msm: init panel orientation property arm64: dts: mt8183: Add panel rotation
.../arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 1 + drivers/gpu/drm/drm_connector.c | 58 ++++++++++++++----- drivers/gpu/drm/mediatek/mtk_dsi.c | 7 +++ drivers/gpu/drm/msm/dsi/dsi_manager.c | 4 ++ include/drm/drm_connector.h | 2 + 5 files changed, 59 insertions(+), 13 deletions(-)
On Mon, May 30, 2022 at 4:53 PM Hans de Goede hdegoede@redhat.com wrote:
Hi,
On 5/30/22 10:19, Hsin-Yi Wang wrote:
Some drivers, eg. mtk_drm and msm_drm, rely on the panel to set the orientation. Panel calls drm_connector_set_panel_orientation() to create orientation property and sets the value. However, connector properties can't be created after drm_dev_register() is called. The goal is to separate the orientation property creation, so drm drivers can create it earlier before drm_dev_register().
Sorry for jumping in pretty late in the discussion (based on the v10 I seem to have missed this before).
This sounds to me like the real issue here is that drm_dev_register() is getting called too early?
Right.
To me it seems sensible to delay calling drm_dev_register() and thus allowing userspace to start detecting available displays + features until after the panel has been probed.
Most panels set this value very late, in .get_modes callback (since it is when the connector is known), though the value was known during panel probe.
I think we can also let drm check if they have remote panel nodes: If there is a panel and the panel sets the orientation, let the drm read this value and set the property. Does this workflow sound reasonable?
The corresponding patch to implement this: https://patchwork.kernel.org/project/linux-mediatek/patch/20220530113033.124...
Thanks
I see a devicetree patch in this series, so I guess that the panel is described in devicetree. Especially in the case of devicetree I would expect the kernel to have enough info to do the right thing and make sure the panel is probed before calling drm_dev_register() ?
Regards,
Hans
After this series, drm_connector_set_panel_orientation() works like before. It won't affect existing callers of drm_connector_set_panel_orientation(). The only difference is that some drm drivers can call drm_connector_init_panel_orientation_property() earlier.
Hsin-Yi Wang (4): gpu: drm: separate panel orientation property creating and value setting drm/mediatek: init panel orientation property drm/msm: init panel orientation property arm64: dts: mt8183: Add panel rotation
.../arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 1 + drivers/gpu/drm/drm_connector.c | 58 ++++++++++++++----- drivers/gpu/drm/mediatek/mtk_dsi.c | 7 +++ drivers/gpu/drm/msm/dsi/dsi_manager.c | 4 ++ include/drm/drm_connector.h | 2 + 5 files changed, 59 insertions(+), 13 deletions(-)
Hi,
On 5/30/22 13:34, Hsin-Yi Wang wrote:
On Mon, May 30, 2022 at 4:53 PM Hans de Goede hdegoede@redhat.com wrote:
Hi,
On 5/30/22 10:19, Hsin-Yi Wang wrote:
Some drivers, eg. mtk_drm and msm_drm, rely on the panel to set the orientation. Panel calls drm_connector_set_panel_orientation() to create orientation property and sets the value. However, connector properties can't be created after drm_dev_register() is called. The goal is to separate the orientation property creation, so drm drivers can create it earlier before drm_dev_register().
Sorry for jumping in pretty late in the discussion (based on the v10 I seem to have missed this before).
This sounds to me like the real issue here is that drm_dev_register() is getting called too early?
Right.
To me it seems sensible to delay calling drm_dev_register() and thus allowing userspace to start detecting available displays + features until after the panel has been probed.
Most panels set this value very late, in .get_modes callback (since it is when the connector is known), though the value was known during panel probe.
Hmm I would expect the main drm/kms driver to register the drm_connector object after probing the panel, right ?
So maybe this is a problem with the panel API? How about adding separate callback to the panel API to get the orientation, which the main drm/kms driver can then call before registering the connector ?
And then have the main drm/kms driver call drm_connector_set_panel_orientation() with the returned orientation on the connecter before registering it.
The new get_orientation callback for the panel should of course be optional (IOW amy be NULL), so we probably want a small helper for drivers using panel (sub)drivers to take care of the process of getting the panel orientation from the panel (if supported) and then setting it on the connector.
I think we can also let drm check if they have remote panel nodes: If there is a panel and the panel sets the orientation, let the drm read this value and set the property. Does this workflow sound reasonable?
The corresponding patch to implement this: https://patchwork.kernel.org/project/linux-mediatek/patch/20220530113033.124...
That is a suprisingly small patch (which is good). I guess that my suggestion to add a new panel driver callback to get the orientation would be a bit bigget then this. Still I think that that would be a bit cleaner, as it would also solve this for cases where the orientation comes from the panel itself (through say some EDID extenstion) rather then from devicetree.
Still I think either way should be acceptable upstream.
Opinions from other drm devs on the above are very much welcome!
Your small patch nicely avoids the probe ordering problem, so it is much better then this patch series.
Regards,
Hans
Thanks
I see a devicetree patch in this series, so I guess that the panel is described in devicetree. Especially in the case of devicetree I would expect the kernel to have enough info to do the right thing and make sure the panel is probed before calling drm_dev_register() ?
Regards,
Hans
After this series, drm_connector_set_panel_orientation() works like before. It won't affect existing callers of drm_connector_set_panel_orientation(). The only difference is that some drm drivers can call drm_connector_init_panel_orientation_property() earlier.
Hsin-Yi Wang (4): gpu: drm: separate panel orientation property creating and value setting drm/mediatek: init panel orientation property drm/msm: init panel orientation property arm64: dts: mt8183: Add panel rotation
.../arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 1 + drivers/gpu/drm/drm_connector.c | 58 ++++++++++++++----- drivers/gpu/drm/mediatek/mtk_dsi.c | 7 +++ drivers/gpu/drm/msm/dsi/dsi_manager.c | 4 ++ include/drm/drm_connector.h | 2 + 5 files changed, 59 insertions(+), 13 deletions(-)
On Tue, May 31, 2022 at 6:56 PM Hans de Goede hdegoede@redhat.com wrote:
Hi,
On 5/30/22 13:34, Hsin-Yi Wang wrote:
On Mon, May 30, 2022 at 4:53 PM Hans de Goede hdegoede@redhat.com wrote:
Hi,
On 5/30/22 10:19, Hsin-Yi Wang wrote:
Some drivers, eg. mtk_drm and msm_drm, rely on the panel to set the orientation. Panel calls drm_connector_set_panel_orientation() to create orientation property and sets the value. However, connector properties can't be created after drm_dev_register() is called. The goal is to separate the orientation property creation, so drm drivers can create it earlier before drm_dev_register().
Sorry for jumping in pretty late in the discussion (based on the v10 I seem to have missed this before).
This sounds to me like the real issue here is that drm_dev_register() is getting called too early?
Right.
To me it seems sensible to delay calling drm_dev_register() and thus allowing userspace to start detecting available displays + features until after the panel has been probed.
Most panels set this value very late, in .get_modes callback (since it is when the connector is known), though the value was known during panel probe.
Hmm I would expect the main drm/kms driver to register the drm_connector object after probing the panel, right ?
So maybe this is a problem with the panel API? How about adding separate callback to the panel API to get the orientation, which the main drm/kms driver can then call before registering the connector ?
And then have the main drm/kms driver call drm_connector_set_panel_orientation() with the returned orientation on the connecter before registering it.
The new get_orientation callback for the panel should of course be optional (IOW amy be NULL), so we probably want a small helper for drivers using panel (sub)drivers to take care of the process of getting the panel orientation from the panel (if supported) and then setting it on the connector.
Hi Hans,
Thanks for the suggestion. I've sent a new version for this: https://patchwork.kernel.org/project/dri-devel/patch/20220601081823.1038797-...
Panel can implement the optional callback to return the orientation property, while drm/kms driver will call a drm API to get the value then they can call drm_connector_set_panel_orientation(). Panel .get_mode will still call drm_connector_set_panel_orientation() but now it will be a no-op as the value was set by drm/kms driver previously.
This is similar to the small patch below: https://patchwork.kernel.org/project/linux-mediatek/patch/20220530113033.124... But it's now using the panel API.
I think we can also let drm check if they have remote panel nodes: If there is a panel and the panel sets the orientation, let the drm read this value and set the property. Does this workflow sound reasonable?
The corresponding patch to implement this: https://patchwork.kernel.org/project/linux-mediatek/patch/20220530113033.124...
That is a suprisingly small patch (which is good). I guess that my suggestion to add a new panel driver callback to get the orientation would be a bit bigget then this. Still I think that that would be a bit cleaner, as it would also solve this for cases where the orientation comes from the panel itself (through say some EDID extenstion) rather then from devicetree.
Still I think either way should be acceptable upstream.
Opinions from other drm devs on the above are very much welcome!
Your small patch nicely avoids the probe ordering problem, so it is much better then this patch series.
Regards,
Hans
Thanks
I see a devicetree patch in this series, so I guess that the panel is described in devicetree. Especially in the case of devicetree I would expect the kernel to have enough info to do the right thing and make sure the panel is probed before calling drm_dev_register() ?
Regards,
Hans
After this series, drm_connector_set_panel_orientation() works like before. It won't affect existing callers of drm_connector_set_panel_orientation(). The only difference is that some drm drivers can call drm_connector_init_panel_orientation_property() earlier.
Hsin-Yi Wang (4): gpu: drm: separate panel orientation property creating and value setting drm/mediatek: init panel orientation property drm/msm: init panel orientation property arm64: dts: mt8183: Add panel rotation
.../arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 1 + drivers/gpu/drm/drm_connector.c | 58 ++++++++++++++----- drivers/gpu/drm/mediatek/mtk_dsi.c | 7 +++ drivers/gpu/drm/msm/dsi/dsi_manager.c | 4 ++ include/drm/drm_connector.h | 2 + 5 files changed, 59 insertions(+), 13 deletions(-)
dri-devel@lists.freedesktop.org