<br><br>On Monday, May 3, 2021, Hans de Goede <<a href="mailto:hdegoede@redhat.com">hdegoede@redhat.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Heikki Krogerus <<a href="mailto:heikki.krogerus@linux.intel.com">heikki.krogerus@linux.intel.<wbr>com</a>><br>
<br>
On Intel platforms we know that the ACPI connector device<br>
node order will follow the order the driver (i915) decides.<br>
The decision is made using the custom Intel ACPI OpRegion<br>
(intel_opregion.c), though the driver does not actually know<br>
that the values it sends to ACPI there are used for<br>
associating a device node for the connectors, and assigning<br>
address for them.<br>
<br>
In reality that custom Intel ACPI OpRegion actually violates<br>
ACPI specification (we supply dynamic information to objects<br>
that are defined static, for example _ADR), however, it<br>
makes assigning correct connector node for a connector entry<br>
straightforward (it's one-on-one mapping).<br>
<br>
Signed-off-by: Heikki Krogerus <<a href="mailto:heikki.krogerus@linux.intel.com">heikki.krogerus@linux.intel.<wbr>com</a>><br>
[<a href="mailto:hdegoede@redhat.com">hdegoede@redhat.com</a>: Move intel_acpi_assign_connector_<wbr>fwnodes() to<br>
intel_acpi.c]<br>
Signed-off-by: Hans de Goede <<a href="mailto:hdegoede@redhat.com">hdegoede@redhat.com</a>><br>
---<br>
drivers/gpu/drm/i915/display/<wbr>intel_acpi.c | 40 ++++++++++++++++++++<br>
drivers/gpu/drm/i915/display/<wbr>intel_acpi.h | 3 ++<br>
drivers/gpu/drm/i915/display/<wbr>intel_display.c | 1 +<br>
3 files changed, 44 insertions(+)<br>
<br>
diff --git a/drivers/gpu/drm/i915/<wbr>display/intel_acpi.c b/drivers/gpu/drm/i915/<wbr>display/intel_acpi.c<br>
index 833d0c1be4f1..9f266dfda7dd 100644<br>
--- a/drivers/gpu/drm/i915/<wbr>display/intel_acpi.c<br>
+++ b/drivers/gpu/drm/i915/<wbr>display/intel_acpi.c<br>
@@ -263,3 +263,43 @@ void intel_acpi_device_id_update(<wbr>struct drm_i915_private *dev_priv)<br>
}<br>
drm_connector_list_iter_end(&<wbr>conn_iter);<br>
}<br>
+<br>
+/* NOTE: The connector order must be final before this is called. */<br>
+void intel_acpi_assign_connector_<wbr>fwnodes(struct drm_i915_private *i915)<br>
+{<br>
+ struct drm_connector_list_iter conn_iter;<br>
+ struct drm_device *drm_dev = &i915->drm;<br>
+ struct device *kdev = &drm_dev->pdev->dev;<br>
+ struct fwnode_handle *fwnode = NULL;<br>
+ struct drm_connector *connector;<br>
+ struct acpi_device *adev;<br>
+<br>
+ drm_connector_list_iter_begin(<wbr>drm_dev, &conn_iter);<br>
+ drm_for_each_connector_iter(<wbr>connector, &conn_iter) {<br>
+ /* Always getting the next, even when the last was not used. */<br>
+ fwnode = device_get_next_child_node(<wbr>kdev, fwnode);<br>
+ if (!fwnode)<br>
+ break;</blockquote><div><br></div><div><br></div><div>Who is dropping reference counting on fwnode ?</div><div><br></div><div>I’m in the middle of a pile of fixes for fwnode refcounting when for_each_child or get_next_child is used. So, please double check you drop a reference.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+ switch (connector->connector_type) {<br>
+ case DRM_MODE_CONNECTOR_LVDS:<br>
+ case DRM_MODE_CONNECTOR_eDP:<br>
+ case DRM_MODE_CONNECTOR_DSI:<br>
+ /*<br>
+ * Integrated displays have a specific address 0x1f on<br>
+ * most Intel platforms, but not on all of them.<br>
+ */<br>
+ adev = acpi_find_child_device(ACPI_<wbr>COMPANION(kdev),<br>
+ 0x1f, 0);<br>
+ if (adev) {<br>
+ connector->fwnode = acpi_fwnode_handle(adev);<br>
+ break;<br>
+ }<br>
+ fallthrough;<br>
+ default:<br>
+ connector->fwnode = fwnode;<br>
+ break;<br>
+ }<br>
+ }<br>
+ drm_connector_list_iter_end(&<wbr>conn_iter);<br>
+}<br>
diff --git a/drivers/gpu/drm/i915/<wbr>display/intel_acpi.h b/drivers/gpu/drm/i915/<wbr>display/intel_acpi.h<br>
index e8b068661d22..d2435691f4b5 100644<br>
--- a/drivers/gpu/drm/i915/<wbr>display/intel_acpi.h<br>
+++ b/drivers/gpu/drm/i915/<wbr>display/intel_acpi.h<br>
@@ -12,11 +12,14 @@ struct drm_i915_private;<br>
void intel_register_dsm_handler(<wbr>void);<br>
void intel_unregister_dsm_handler(<wbr>void);<br>
void intel_acpi_device_id_update(<wbr>struct drm_i915_private *i915);<br>
+void intel_acpi_assign_connector_<wbr>fwnodes(struct drm_i915_private *i915);<br>
#else<br>
static inline void intel_register_dsm_handler(<wbr>void) { return; }<br>
static inline void intel_unregister_dsm_handler(<wbr>void) { return; }<br>
static inline<br>
void intel_acpi_device_id_update(<wbr>struct drm_i915_private *i915) { return; }<br>
+static inline<br>
+void intel_acpi_assign_connector_<wbr>fwnodes(struct drm_i915_private *i915) { return; }<br>
#endif /* CONFIG_ACPI */<br>
<br>
#endif /* __INTEL_ACPI_H__ */<br>
diff --git a/drivers/gpu/drm/i915/<wbr>display/intel_display.c b/drivers/gpu/drm/i915/<wbr>display/intel_display.c<br>
index 828ef4c5625f..87cad549632c 100644<br>
--- a/drivers/gpu/drm/i915/<wbr>display/intel_display.c<br>
+++ b/drivers/gpu/drm/i915/<wbr>display/intel_display.c<br>
@@ -14970,6 +14970,7 @@ int intel_modeset_init_nogem(<wbr>struct drm_i915_private *i915)<br>
<br>
drm_modeset_lock_all(dev);<br>
intel_modeset_setup_hw_state(<wbr>dev, dev->mode_config.acquire_ctx);<br>
+ intel_acpi_assign_connector_<wbr>fwnodes(i915);<br>
drm_modeset_unlock_all(dev);<br>
<br>
for_each_intel_crtc(dev, crtc) {<br>
-- <br>
2.31.1<br>
<br>
</blockquote><br><br>-- <br>With Best Regards,<br>Andy Shevchenko<br><br><br>