mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-16 15:34:48 +08:00
drm/nouveau: Fix drm-core using atomic code-paths on pre-nv50 hardware
We do not support atomic modesetting on pre-nv50 hardware, but until now our connector code was setting drm_connector->state on pre-nv50 hardware. This causes the core to enter atomic modesetting paths in at least: 1. drm_connector_get_encoder(), returning connector->state->best_encoder which is always 0, causing us to always report 0 as encoder_id in the drmModeConnector struct returned by drmModeGetConnector(). 2. drm_encoder_get_crtc(), returning NULL because uses_atomic get set, causing us to always report 0 as crtc_id in the drmModeEncoder struct returned by drmModeGetEncoder() Which in turn confuses userspace, at least plymouth thinks that the pipe has changed because of this and tries to reconfigure it unnecessarily. More in general we should not set drm_connector->state in the non-atomic code as this violates the drm-core's expectations. This commit fixes this by using a nouveau_conn_atom struct embedded in the nouveau_connector struct for property handling in the non-atomic case. Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1706557 Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
37a68eab4c
commit
64d17f25dc
@ -245,14 +245,22 @@ nouveau_conn_atomic_duplicate_state(struct drm_connector *connector)
|
||||
void
|
||||
nouveau_conn_reset(struct drm_connector *connector)
|
||||
{
|
||||
struct nouveau_connector *nv_connector = nouveau_connector(connector);
|
||||
struct nouveau_conn_atom *asyc;
|
||||
|
||||
if (WARN_ON(!(asyc = kzalloc(sizeof(*asyc), GFP_KERNEL))))
|
||||
return;
|
||||
if (drm_drv_uses_atomic_modeset(connector->dev)) {
|
||||
if (WARN_ON(!(asyc = kzalloc(sizeof(*asyc), GFP_KERNEL))))
|
||||
return;
|
||||
|
||||
if (connector->state)
|
||||
nouveau_conn_atomic_destroy_state(connector,
|
||||
connector->state);
|
||||
|
||||
__drm_atomic_helper_connector_reset(connector, &asyc->state);
|
||||
} else {
|
||||
asyc = &nv_connector->properties_state;
|
||||
}
|
||||
|
||||
if (connector->state)
|
||||
nouveau_conn_atomic_destroy_state(connector, connector->state);
|
||||
__drm_atomic_helper_connector_reset(connector, &asyc->state);
|
||||
asyc->dither.mode = DITHERING_MODE_AUTO;
|
||||
asyc->dither.depth = DITHERING_DEPTH_AUTO;
|
||||
asyc->scaler.mode = DRM_MODE_SCALE_NONE;
|
||||
@ -276,8 +284,14 @@ void
|
||||
nouveau_conn_attach_properties(struct drm_connector *connector)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct nouveau_conn_atom *armc = nouveau_conn_atom(connector->state);
|
||||
struct nouveau_display *disp = nouveau_display(dev);
|
||||
struct nouveau_connector *nv_connector = nouveau_connector(connector);
|
||||
struct nouveau_conn_atom *armc;
|
||||
|
||||
if (drm_drv_uses_atomic_modeset(connector->dev))
|
||||
armc = nouveau_conn_atom(connector->state);
|
||||
else
|
||||
armc = &nv_connector->properties_state;
|
||||
|
||||
/* Init DVI-I specific properties. */
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_DVII)
|
||||
@ -748,9 +762,9 @@ static int
|
||||
nouveau_connector_set_property(struct drm_connector *connector,
|
||||
struct drm_property *property, uint64_t value)
|
||||
{
|
||||
struct nouveau_conn_atom *asyc = nouveau_conn_atom(connector->state);
|
||||
struct nouveau_connector *nv_connector = nouveau_connector(connector);
|
||||
struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
|
||||
struct nouveau_conn_atom *asyc = &nv_connector->properties_state;
|
||||
struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
|
||||
int ret;
|
||||
|
||||
|
@ -118,6 +118,12 @@ struct nouveau_connector {
|
||||
#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
|
||||
struct nouveau_backlight *backlight;
|
||||
#endif
|
||||
/*
|
||||
* Our connector property code expects a nouveau_conn_atom struct
|
||||
* even on pre-nv50 where we do not support atomic. This embedded
|
||||
* version gets used in the non atomic modeset case.
|
||||
*/
|
||||
struct nouveau_conn_atom properties_state;
|
||||
};
|
||||
|
||||
static inline struct nouveau_connector *nouveau_connector(
|
||||
|
Loading…
Reference in New Issue
Block a user