Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8dfaa8a7 authored by Michel Dänzer's avatar Michel Dänzer Committed by Dave Airlie
Browse files

drm/radeon/kms: Get LVDS native mode details from EDID if necessary.



Fixes RMX problems on older Apple laptops which don't have an x86 BIOS ROM.

Signed-off-by: default avatarMichel Dänzer <daenzer@vmware.com>
Signed-off-by: default avatarDave Airlie <airlied@linux.ie>
parent f657c2a7
Loading
Loading
Loading
Loading
+8 −4
Original line number Original line Diff line number Diff line
@@ -863,8 +863,10 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder
	int tmp, i;
	int tmp, i;
	struct radeon_encoder_lvds *lvds = NULL;
	struct radeon_encoder_lvds *lvds = NULL;


	if (rdev->bios == NULL)
	if (rdev->bios == NULL) {
		return radeon_legacy_get_lvds_info_from_regs(rdev);
		lvds = radeon_legacy_get_lvds_info_from_regs(rdev);
		goto out;
	}


	lcd_info = combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE);
	lcd_info = combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE);


@@ -965,11 +967,13 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder
				lvds->native_mode.flags = 0;
				lvds->native_mode.flags = 0;
			}
			}
		}
		}
		encoder->native_mode = lvds->native_mode;
	} else {
	} else {
		DRM_INFO("No panel info found in BIOS\n");
		DRM_INFO("No panel info found in BIOS\n");
		return radeon_legacy_get_lvds_info_from_regs(rdev);
		lvds = radeon_legacy_get_lvds_info_from_regs(rdev);
	}
	}
out:
	if (lvds)
		encoder->native_mode = lvds->native_mode;
	return lvds;
	return lvds;
}
}


+33 −1
Original line number Original line Diff line number Diff line
@@ -227,6 +227,36 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr
	return 0;
	return 0;
}
}


static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder,
					  struct drm_connector *connector)
{
	struct radeon_encoder *radeon_encoder =	to_radeon_encoder(encoder);
	struct radeon_native_mode *native_mode = &radeon_encoder->native_mode;

	/* Try to get native mode details from EDID if necessary */
	if (!native_mode->dotclock) {
		struct drm_display_mode *t, *mode;

		list_for_each_entry_safe(mode, t, &connector->probed_modes, head) {
			if (mode->hdisplay == native_mode->panel_xres &&
			    mode->vdisplay == native_mode->panel_yres) {
				native_mode->hblank = mode->htotal - mode->hdisplay;
				native_mode->hoverplus = mode->hsync_start - mode->hdisplay;
				native_mode->hsync_width = mode->hsync_end - mode->hsync_start;
				native_mode->vblank = mode->vtotal - mode->vdisplay;
				native_mode->voverplus = mode->vsync_start - mode->vdisplay;
				native_mode->vsync_width = mode->vsync_end - mode->vsync_start;
				native_mode->dotclock = mode->clock;
				DRM_INFO("Determined LVDS native mode details from EDID\n");
				break;
			}
		}
	}
	if (!native_mode->dotclock) {
		DRM_INFO("No LVDS native mode details, disabling RMX\n");
		radeon_encoder->rmx_type = RMX_OFF;
	}
}


static int radeon_lvds_get_modes(struct drm_connector *connector)
static int radeon_lvds_get_modes(struct drm_connector *connector)
{
{
@@ -239,9 +269,11 @@ static int radeon_lvds_get_modes(struct drm_connector *connector)
		ret = radeon_ddc_get_modes(radeon_connector);
		ret = radeon_ddc_get_modes(radeon_connector);
		if (ret > 0) {
		if (ret > 0) {
			encoder = radeon_best_single_encoder(connector);
			encoder = radeon_best_single_encoder(connector);
			if (encoder)
			if (encoder) {
				radeon_fixup_lvds_native_mode(encoder, connector);
				/* add scaled modes */
				/* add scaled modes */
				radeon_add_common_modes(encoder, connector);
				radeon_add_common_modes(encoder, connector);
			}
			return ret;
			return ret;
		}
		}
	}
	}