drm/amd/display/amdgpu_dm: Make amdgpu_dm_register_backlight_device() take an amdgpu_...
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / display / amdgpu_dm / amdgpu_dm.c
index 1c69353..aee7950 100644 (file)
@@ -820,15 +820,14 @@ static void dm_dmub_outbox1_low_irq(void *interrupt_params)
                                        DRM_ERROR("Failed to allocate dmub_hpd_wrk");
                                        return;
                                }
-                               dmub_hpd_wrk->dmub_notify = kzalloc(sizeof(struct dmub_notification), GFP_ATOMIC);
+                               dmub_hpd_wrk->dmub_notify = kmemdup(&notify, sizeof(struct dmub_notification),
+                                                                   GFP_ATOMIC);
                                if (!dmub_hpd_wrk->dmub_notify) {
                                        kfree(dmub_hpd_wrk);
                                        DRM_ERROR("Failed to allocate dmub_hpd_wrk->dmub_notify");
                                        return;
                                }
                                INIT_WORK(&dmub_hpd_wrk->handle_hpd_work, dm_handle_hpd_work);
-                               if (dmub_hpd_wrk->dmub_notify)
-                                       memcpy(dmub_hpd_wrk->dmub_notify, &notify, sizeof(struct dmub_notification));
                                dmub_hpd_wrk->adev = adev;
                                if (notify.type == DMUB_NOTIFICATION_HPD) {
                                        plink = adev->dm.dc->links[notify.link_index];
@@ -2976,30 +2975,18 @@ static struct drm_mode_config_helper_funcs amdgpu_dm_mode_config_helperfuncs = {
 static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
 {
        struct amdgpu_dm_backlight_caps *caps;
-       struct amdgpu_display_manager *dm;
        struct drm_connector *conn_base;
        struct amdgpu_device *adev;
-       struct dc_link *link = NULL;
        struct drm_luminance_range_info *luminance_range;
-       int i;
-
-       if (!aconnector || !aconnector->dc_link)
-               return;
 
-       link = aconnector->dc_link;
-       if (link->connector_signal != SIGNAL_TYPE_EDP)
+       if (aconnector->bl_idx == -1 ||
+           aconnector->dc_link->connector_signal != SIGNAL_TYPE_EDP)
                return;
 
        conn_base = &aconnector->base;
        adev = drm_to_adev(conn_base->dev);
-       dm = &adev->dm;
-       for (i = 0; i < dm->num_of_edps; i++) {
-               if (link == dm->backlight_link[i])
-                       break;
-       }
-       if (i >= dm->num_of_edps)
-               return;
-       caps = &dm->backlight_caps[i];
+
+       caps = &adev->dm.backlight_caps[aconnector->bl_idx];
        caps->ext_caps = &aconnector->dc_link->dpcd_sink_ext_caps;
        caps->aux_support = false;
 
@@ -4190,16 +4177,15 @@ static const struct backlight_ops amdgpu_dm_backlight_ops = {
 };
 
 static void
-amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm)
+amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector)
 {
-       char bl_name[16];
+       struct drm_device *drm = aconnector->base.dev;
+       struct amdgpu_display_manager *dm = &drm_to_adev(drm)->dm;
        struct backlight_properties props = { 0 };
-
-       amdgpu_dm_update_backlight_caps(dm, dm->num_of_edps);
-       dm->brightness[dm->num_of_edps] = AMDGPU_MAX_BL_LEVEL;
+       char bl_name[16];
 
        if (!acpi_video_backlight_use_native()) {
-               drm_info(adev_to_drm(dm->adev), "Skipping amdgpu DM backlight registration\n");
+               drm_info(drm, "Skipping amdgpu DM backlight registration\n");
                /* Try registering an ACPI video backlight device instead. */
                acpi_video_register_backlight();
                return;
@@ -4210,17 +4196,15 @@ amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm)
        props.type = BACKLIGHT_RAW;
 
        snprintf(bl_name, sizeof(bl_name), "amdgpu_bl%d",
-                adev_to_drm(dm->adev)->primary->index + dm->num_of_edps);
+                drm->primary->index + aconnector->bl_idx);
 
-       dm->backlight_dev[dm->num_of_edps] = backlight_device_register(bl_name,
-                                                                      adev_to_drm(dm->adev)->dev,
-                                                                      dm,
-                                                                      &amdgpu_dm_backlight_ops,
-                                                                      &props);
+       dm->backlight_dev[aconnector->bl_idx] =
+               backlight_device_register(bl_name, drm->dev, dm,
+                                         &amdgpu_dm_backlight_ops, &props);
 
-       if (IS_ERR(dm->backlight_dev[dm->num_of_edps])) {
+       if (IS_ERR(dm->backlight_dev[aconnector->bl_idx])) {
                DRM_ERROR("DM: Backlight registration failed!\n");
-               dm->backlight_dev[dm->num_of_edps] = NULL;
+               dm->backlight_dev[aconnector->bl_idx] = NULL;
        } else
                DRM_DEBUG_DRIVER("DM: Registered Backlight device: %s\n", bl_name);
 }
@@ -4266,24 +4250,36 @@ static int initialize_plane(struct amdgpu_display_manager *dm,
 }
 
 
-static void register_backlight_device(struct amdgpu_display_manager *dm,
-                                     struct dc_link *link)
+static void setup_backlight_device(struct amdgpu_display_manager *dm,
+                                  struct amdgpu_dm_connector *aconnector)
 {
-       if ((link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) &&
-           link->type != dc_connection_none) {
-               /*
-                * Event if registration failed, we should continue with
-                * DM initialization because not having a backlight control
-                * is better then a black screen.
-                */
-               if (!dm->backlight_dev[dm->num_of_edps])
-                       amdgpu_dm_register_backlight_device(dm);
+       struct dc_link *link = aconnector->dc_link;
+       int bl_idx = dm->num_of_edps;
 
-               if (dm->backlight_dev[dm->num_of_edps]) {
-                       dm->backlight_link[dm->num_of_edps] = link;
-                       dm->num_of_edps++;
-               }
+       if (!(link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) ||
+           link->type == dc_connection_none)
+               return;
+
+       if (dm->num_of_edps >= AMDGPU_DM_MAX_NUM_EDP) {
+               drm_warn(adev_to_drm(dm->adev), "Too much eDP connections, skipping backlight setup for additional eDPs\n");
+               return;
        }
+
+       aconnector->bl_idx = bl_idx;
+
+       amdgpu_dm_update_backlight_caps(dm, bl_idx);
+       dm->brightness[bl_idx] = AMDGPU_MAX_BL_LEVEL;
+
+       amdgpu_dm_register_backlight_device(aconnector);
+       if (!dm->backlight_dev[bl_idx]) {
+               aconnector->bl_idx = -1;
+               return;
+       }
+
+       dm->backlight_link[bl_idx] = link;
+       dm->num_of_edps++;
+
+       update_connector_ext_caps(aconnector);
 }
 
 static void amdgpu_set_panel_orientation(struct drm_connector *connector);
@@ -4463,10 +4459,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
 
                        if (ret) {
                                amdgpu_dm_update_connector_after_detect(aconnector);
-                               register_backlight_device(dm, link);
-
-                               if (dm->num_of_edps)
-                                       update_connector_ext_caps(aconnector);
+                               setup_backlight_device(dm, aconnector);
 
                                if (psr_feature_enabled)
                                        amdgpu_dm_set_psr_caps(link);
@@ -6242,10 +6235,8 @@ static void amdgpu_dm_connector_unregister(struct drm_connector *connector)
 static void amdgpu_dm_connector_destroy(struct drm_connector *connector)
 {
        struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
-       const struct dc_link *link = aconnector->dc_link;
        struct amdgpu_device *adev = drm_to_adev(connector->dev);
        struct amdgpu_display_manager *dm = &adev->dm;
-       int i;
 
        /*
         * Call only if mst_mgr was initialized before since it's not done
@@ -6254,11 +6245,9 @@ static void amdgpu_dm_connector_destroy(struct drm_connector *connector)
        if (aconnector->mst_mgr.dev)
                drm_dp_mst_topology_mgr_destroy(&aconnector->mst_mgr);
 
-       for (i = 0; i < dm->num_of_edps; i++) {
-               if ((link == dm->backlight_link[i]) && dm->backlight_dev[i]) {
-                       backlight_device_unregister(dm->backlight_dev[i]);
-                       dm->backlight_dev[i] = NULL;
-               }
+       if (aconnector->bl_idx != -1) {
+               backlight_device_unregister(dm->backlight_dev[aconnector->bl_idx]);
+               dm->backlight_dev[aconnector->bl_idx] = NULL;
        }
 
        if (aconnector->dc_em_sink)
@@ -7228,6 +7217,7 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
                aconnector->base.funcs->reset(&aconnector->base);
 
        aconnector->connector_id = link_index;
+       aconnector->bl_idx = -1;
        aconnector->dc_link = link;
        aconnector->base.interlace_allowed = false;
        aconnector->base.doublescan_allowed = false;
@@ -7282,7 +7272,6 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
        if (!aconnector->mst_root)
                drm_connector_attach_max_bpc_property(&aconnector->base, 8, 16);
 
-       /* This defaults to the max in the range, but we want 8bpc for non-edp. */
        aconnector->base.state->max_bpc = 16;
        aconnector->base.state->max_requested_bpc = aconnector->base.state->max_bpc;