drm/amd: Fix logic error in sienna_cichlid_update_pcie_parameters()
authorjsg <jsg@openbsd.org>
Wed, 18 Oct 2023 01:52:20 +0000 (01:52 +0000)
committerjsg <jsg@openbsd.org>
Wed, 18 Oct 2023 01:52:20 +0000 (01:52 +0000)
From Mario Limonciello
d2894c4f473ab71cd68ef0f9b086148bb2c02132 in linux-6.1.y/6.1.57
2a1fe39a5be785e962e387146aed34fa9a829f3f in mainline linux

sys/dev/pci/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c

index 60deb11..4248bc2 100644 (file)
@@ -2081,36 +2081,43 @@ static int sienna_cichlid_display_disable_memory_clock_switch(struct smu_context
        return ret;
 }
 
+#ifndef MAX
+#define MAX(a, b)      ((a) > (b) ? (a) : (b))
+#endif
+
 static int sienna_cichlid_update_pcie_parameters(struct smu_context *smu,
                                         uint32_t pcie_gen_cap,
                                         uint32_t pcie_width_cap)
 {
        struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
        struct smu_11_0_pcie_table *pcie_table = &dpm_context->dpm_tables.pcie_table;
-       u32 smu_pcie_arg;
+       uint8_t *table_member1, *table_member2;
+       uint32_t min_gen_speed, max_gen_speed;
+       uint32_t min_lane_width, max_lane_width;
+       uint32_t smu_pcie_arg;
        int ret, i;
 
-       /* PCIE gen speed and lane width override */
-       if (!amdgpu_device_pcie_dynamic_switching_supported()) {
-               if (pcie_table->pcie_gen[NUM_LINK_LEVELS - 1] < pcie_gen_cap)
-                       pcie_gen_cap = pcie_table->pcie_gen[NUM_LINK_LEVELS - 1];
+       GET_PPTABLE_MEMBER(PcieGenSpeed, &table_member1);
+       GET_PPTABLE_MEMBER(PcieLaneCount, &table_member2);
 
-               if (pcie_table->pcie_lane[NUM_LINK_LEVELS - 1] < pcie_width_cap)
-                       pcie_width_cap = pcie_table->pcie_lane[NUM_LINK_LEVELS - 1];
+       min_gen_speed = MAX(0, table_member1[0]);
+       max_gen_speed = MIN(pcie_gen_cap, table_member1[1]);
+       min_gen_speed = min_gen_speed > max_gen_speed ?
+                       max_gen_speed : min_gen_speed;
+       min_lane_width = MAX(1, table_member2[0]);
+       max_lane_width = MIN(pcie_width_cap, table_member2[1]);
+       min_lane_width = min_lane_width > max_lane_width ?
+                        max_lane_width : min_lane_width;
 
-               /* Force all levels to use the same settings */
-               for (i = 0; i < NUM_LINK_LEVELS; i++) {
-                       pcie_table->pcie_gen[i] = pcie_gen_cap;
-                       pcie_table->pcie_lane[i] = pcie_width_cap;
-               }
+       if (!amdgpu_device_pcie_dynamic_switching_supported()) {
+               pcie_table->pcie_gen[0] = max_gen_speed;
+               pcie_table->pcie_lane[0] = max_lane_width;
        } else {
-               for (i = 0; i < NUM_LINK_LEVELS; i++) {
-                       if (pcie_table->pcie_gen[i] > pcie_gen_cap)
-                               pcie_table->pcie_gen[i] = pcie_gen_cap;
-                       if (pcie_table->pcie_lane[i] > pcie_width_cap)
-                               pcie_table->pcie_lane[i] = pcie_width_cap;
-               }
+               pcie_table->pcie_gen[0] = min_gen_speed;
+               pcie_table->pcie_lane[0] = min_lane_width;
        }
+       pcie_table->pcie_gen[1] = max_gen_speed;
+       pcie_table->pcie_lane[1] = max_lane_width;
 
        for (i = 0; i < NUM_LINK_LEVELS; i++) {
                smu_pcie_arg = (i << 16 |