Hi

Am 30.10.26 um 16:14 schrieb Maxime Ripard:
[...]
+struct drm_connector_state *
+nouveau_conn_atomic_create_state(struct drm_connector *connector)
+{
+       struct nouveau_conn_atom *asyc;
+
+       asyc = kzalloc_obj(*asyc);
+       if (WARN_ON(!asyc))

Since you're here anyway, please use drm_WARN_ON_ONCE(). Plain WARN_ON() doesn't seem a good fit here.

Best regards
Thomas

+               return ERR_PTR(-ENOMEM);
+
+       __drm_atomic_helper_connector_state_init(&asyc->state, connector);
+       nouveau_conn_atom_init(connector, asyc);
+
+       return &asyc->state;
+}
+
  void
  nouveau_conn_attach_properties(struct drm_connector *connector)
@@ -1231,5 +1231,47 @@ static const struct drm_connector_funcs
  nouveau_connector_funcs = {
        .dpms = drm_helper_connector_dpms,
-       .reset = nouveau_conn_reset,
+       .detect = nouveau_connector_detect,
+       .force = nouveau_connector_force,
+       .fill_modes = drm_helper_probe_single_connector_modes,
+       .set_property = nouveau_connector_set_property,
+       .destroy = nouveau_connector_destroy,
+       .atomic_create_state = nouveau_conn_atomic_create_state,
+       .atomic_duplicate_state = nouveau_conn_atomic_duplicate_state,
+       .atomic_destroy_state = nouveau_conn_atomic_destroy_state,
+       .atomic_set_property = nouveau_conn_atomic_set_property,
+       .atomic_get_property = nouveau_conn_atomic_get_property,
+       .late_register = nouveau_connector_late_register,
+       .early_unregister = nouveau_connector_early_unregister,
+};
+
+static const struct drm_connector_funcs
+nouveau_connector_funcs_lvds = {
+       .dpms = drm_helper_connector_dpms,
+       .detect = nouveau_connector_detect_lvds,
+       .force = nouveau_connector_force,
+       .fill_modes = drm_helper_probe_single_connector_modes,
+       .set_property = nouveau_connector_set_property,
+       .destroy = nouveau_connector_destroy,
+       .atomic_create_state = nouveau_conn_atomic_create_state,
+       .atomic_duplicate_state = nouveau_conn_atomic_duplicate_state,
+       .atomic_destroy_state = nouveau_conn_atomic_destroy_state,
+       .atomic_set_property = nouveau_conn_atomic_set_property,
+       .atomic_get_property = nouveau_conn_atomic_get_property,
+       .late_register = nouveau_connector_late_register,
+       .early_unregister = nouveau_connector_early_unregister,
+};
+
+/*
+ * Pre-nv50 doesn't support atomic modesetting: the connector property state
+ * lives in the embedded struct nouveau_connector.properties_state and
+ * drm_connector.state is left alone, as expected from a legacy driver.
+ *
+ * Those connectors must not expose atomic_create_state: the DRM core would
+ * then install the embedded state into drm_connector.state and eventually
+ * pass it to atomic_destroy_state, which frees it.
+ */
+static const struct drm_connector_funcs
+nouveau_connector_funcs_legacy = {
+       .dpms = drm_helper_connector_dpms,
        .detect = nouveau_connector_detect,
        .force = nouveau_connector_force,
@@ -1246,7 +1288,6 @@ nouveau_connector_funcs = {
static const struct drm_connector_funcs
-nouveau_connector_funcs_lvds = {
+nouveau_connector_funcs_lvds_legacy = {
        .dpms = drm_helper_connector_dpms,
-       .reset = nouveau_conn_reset,
        .detect = nouveau_connector_detect_lvds,
        .force = nouveau_connector_force,
@@ -1362,5 +1403,7 @@ nouveau_connector_create(struct drm_device *dev, int 
index)
        struct nouveau_display *disp = nouveau_display(dev);
        struct nouveau_connector *nv_connector = NULL;
+       struct drm_connector_state *conn_state;
        struct drm_connector *connector;
+       const struct drm_connector_funcs *funcs;
        struct drm_connector_list_iter conn_iter;
        int type, ret = 0;
@@ -1459,8 +1502,17 @@ nouveau_connector_create(struct drm_device *dev, int 
index)
type = drm_conntype_from_dcb(nv_connector->type);
-       if (type == DRM_MODE_CONNECTOR_LVDS)
-               drm_connector_init(dev, connector, 
&nouveau_connector_funcs_lvds, type);
-       else
-               drm_connector_init(dev, connector, &nouveau_connector_funcs, 
type);
+       if (type == DRM_MODE_CONNECTOR_LVDS) {
+               if (drm_drv_uses_atomic_modeset(dev))
+                       funcs = &nouveau_connector_funcs_lvds;
+               else
+                       funcs = &nouveau_connector_funcs_lvds_legacy;
+       } else {
+               if (drm_drv_uses_atomic_modeset(dev))
+                       funcs = &nouveau_connector_funcs;
+               else
+                       funcs = &nouveau_connector_funcs_legacy;
+       }
+
+       drm_connector_init(dev, connector, funcs, type);
switch (type) {
@@ -1514,13 +1566,26 @@ nouveau_connector_create(struct drm_device *dev, int 
index)
                                                   nouveau_connector_irq, 
NVIF_CONN_EVENT_V0_IRQ,
                                                   &nv_connector->irq);
-                       if (ret) {
-                               nvif_event_dtor(&nv_connector->hpd);
-                               nvif_conn_dtor(&nv_connector->conn);
+                       if (ret)
                                goto drm_conn_err;
-                       }
                }
        }
- connector->funcs->reset(connector);
+       if (drm_drv_uses_atomic_modeset(dev)) {
+               conn_state = connector->funcs->atomic_create_state(connector);
+               if (IS_ERR(conn_state)) {
+                       ret = PTR_ERR(conn_state);
+                       goto drm_conn_err;
+               }
+               connector->state = conn_state;
+       } else {
+               /* Pre-nv50 keeps its property state embedded in struct
+                * nouveau_connector: drm_connector.state must remain NULL,
+                * the DRM core expects legacy drivers to use
+                * drm_connector.encoder.
+                */
+               nouveau_conn_atom_init(connector,
+                                      &nv_connector->properties_state);
+       }
+
        nouveau_conn_attach_properties(connector);
@@ -1567,4 +1632,8 @@ nouveau_connector_create(struct drm_device *dev, int index) drm_conn_err:
+       nvif_event_dtor(&nv_connector->irq);
+       nvif_event_dtor(&nv_connector->hpd);
+       cancel_work_sync(&nv_connector->irq_work);
+       nvif_conn_dtor(&nv_connector->conn);
        drm_connector_cleanup(connector);
        kfree(nv_connector);
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h 
b/drivers/gpu/drm/nouveau/nouveau_connector.h
index eb292d2ba4bc..02f843648eb8 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.h
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.h
@@ -217,5 +217,6 @@ extern int nouveau_hdmimhz;
void nouveau_conn_attach_properties(struct drm_connector *);
-void nouveau_conn_reset(struct drm_connector *);
+struct drm_connector_state *
+nouveau_conn_atomic_create_state(struct drm_connector *);
  struct drm_connector_state *
  nouveau_conn_atomic_duplicate_state(struct drm_connector *);


--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Stefan Gaiser, Jochen Jaser, Abhinav Puri, (HRB 36809, AG Nürnberg)


Reply via email to