]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amd/display/dm: add support for OEM i2c bus
authorAlex Deucher <alexander.deucher@amd.com>
Tue, 17 Dec 2024 14:55:49 +0000 (09:55 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 13 Feb 2025 02:02:54 +0000 (21:02 -0500)
Expose the OEM i2c bus on boards that support it.
This bus is used for OEM specific features like RGB, etc.

Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h

index 03c6be289bb553941240c998d23f9d2b5c9e5227..508e5a6aa8df3797846021b9432b9a6197c5abf8 100644 (file)
@@ -179,6 +179,8 @@ static int amdgpu_dm_init(struct amdgpu_device *adev);
 static void amdgpu_dm_fini(struct amdgpu_device *adev);
 static bool is_freesync_video_mode(const struct drm_display_mode *mode, struct amdgpu_dm_connector *aconnector);
 static void reset_freesync_config_for_crtc(struct dm_crtc_state *new_crtc_state);
+static struct amdgpu_i2c_adapter *
+create_i2c(struct ddc_service *ddc_service, bool oem);
 
 static enum drm_mode_subconnector get_subconnector_type(struct dc_link *link)
 {
@@ -2893,6 +2895,33 @@ static int amdgpu_dm_smu_write_watermarks_table(struct amdgpu_device *adev)
        return 0;
 }
 
+static int dm_oem_i2c_hw_init(struct amdgpu_device *adev)
+{
+       struct amdgpu_display_manager *dm = &adev->dm;
+       struct amdgpu_i2c_adapter *oem_i2c;
+       struct ddc_service *oem_ddc_service;
+       int r;
+
+       oem_ddc_service = dc_get_oem_i2c_device(adev->dm.dc);
+       if (oem_ddc_service) {
+               oem_i2c = create_i2c(oem_ddc_service, true);
+               if (!oem_i2c) {
+                       dev_info(adev->dev, "Failed to create oem i2c adapter data\n");
+                       return -ENOMEM;
+               }
+
+               r = i2c_add_adapter(&oem_i2c->base);
+               if (r) {
+                       dev_info(adev->dev, "Failed to register oem i2c\n");
+                       kfree(oem_i2c);
+                       return r;
+               }
+               dm->oem_i2c = oem_i2c;
+       }
+
+       return 0;
+}
+
 /**
  * dm_hw_init() - Initialize DC device
  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
@@ -2924,6 +2953,10 @@ static int dm_hw_init(struct amdgpu_ip_block *ip_block)
                return r;
        amdgpu_dm_hpd_init(adev);
 
+       r = dm_oem_i2c_hw_init(adev);
+       if (r)
+               dev_info(adev->dev, "Failed to add OEM i2c bus\n");
+
        return 0;
 }
 
@@ -2939,6 +2972,8 @@ static int dm_hw_fini(struct amdgpu_ip_block *ip_block)
 {
        struct amdgpu_device *adev = ip_block->adev;
 
+       kfree(adev->dm.oem_i2c);
+
        amdgpu_dm_hpd_fini(adev);
 
        amdgpu_dm_irq_fini(adev);
index d2703ca7dff31dd86c9aaa3a37a044c44d7d40f0..ef60e80de19c506f2c43a689532cb40cd4e40562 100644 (file)
@@ -606,6 +606,13 @@ struct amdgpu_display_manager {
         * Bounding box data read from dmub during early initialization for DCN4+
         */
        struct dml2_soc_bb *bb_from_dmub;
+
+       /**
+        * @oem_i2c:
+        *
+        * OEM i2c bus
+        */
+       struct amdgpu_i2c_adapter *oem_i2c;
 };
 
 enum dsc_clock_force_state {