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

Commit de2103e4 authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie
Browse files

drm/radeon/kms: use drm_mode directly for panel modes



This reduces the number of mode format conversions needed
and makes native panel mode support cleaner.

Signed-off-by: default avatarAlex Deucher <alexdeucher@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 5a9bcacc
Loading
Loading
Loading
Loading
+17 −15
Original line number Diff line number Diff line
@@ -798,27 +798,29 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
		if (!lvds)
			return NULL;

		lvds->native_mode.dotclock =
		lvds->native_mode.clock =
		    le16_to_cpu(lvds_info->info.sLCDTiming.usPixClk) * 10;
		lvds->native_mode.panel_xres =
		lvds->native_mode.hdisplay =
		    le16_to_cpu(lvds_info->info.sLCDTiming.usHActive);
		lvds->native_mode.panel_yres =
		lvds->native_mode.vdisplay =
		    le16_to_cpu(lvds_info->info.sLCDTiming.usVActive);
		lvds->native_mode.hblank =
		lvds->native_mode.htotal = lvds->native_mode.hdisplay +
			le16_to_cpu(lvds_info->info.sLCDTiming.usHBlanking_Time);
		lvds->native_mode.hoverplus =
		lvds->native_mode.hsync_start = lvds->native_mode.hdisplay +
			le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncOffset);
		lvds->native_mode.hsync_width =
		lvds->native_mode.hsync_end = lvds->native_mode.hsync_start +
			le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncWidth);
		lvds->native_mode.vblank =
		lvds->native_mode.vtotal = lvds->native_mode.vdisplay +
			le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time);
		lvds->native_mode.voverplus =
		    le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncOffset);
		lvds->native_mode.vsync_width =
		lvds->native_mode.vsync_start = lvds->native_mode.vdisplay +
			le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth);
		lvds->native_mode.vsync_end = lvds->native_mode.vsync_start +
			le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth);
		lvds->panel_pwr_delay =
		    le16_to_cpu(lvds_info->info.usOffDelayInMs);
		lvds->lvds_misc = lvds_info->info.ucLVDS_Misc;
		/* set crtc values */
		drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V);

		encoder->native_mode = lvds->native_mode;
	}
+31 −33
Original line number Diff line number Diff line
@@ -808,25 +808,25 @@ static struct radeon_encoder_lvds *radeon_legacy_get_lvds_info_from_regs(struct
	lvds->panel_blon_delay = (lvds_ss_gen_cntl >> RADEON_LVDS_PWRSEQ_DELAY2_SHIFT) & 0xf;

	if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE)
		lvds->native_mode.panel_yres =
		lvds->native_mode.vdisplay =
		    ((fp_vert_stretch & RADEON_VERT_PANEL_SIZE) >>
		     RADEON_VERT_PANEL_SHIFT) + 1;
	else
		lvds->native_mode.panel_yres =
		lvds->native_mode.vdisplay =
		    (RREG32(RADEON_CRTC_V_TOTAL_DISP) >> 16) + 1;

	if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE)
		lvds->native_mode.panel_xres =
		lvds->native_mode.hdisplay =
		    (((fp_horz_stretch & RADEON_HORZ_PANEL_SIZE) >>
		      RADEON_HORZ_PANEL_SHIFT) + 1) * 8;
	else
		lvds->native_mode.panel_xres =
		lvds->native_mode.hdisplay =
		    ((RREG32(RADEON_CRTC_H_TOTAL_DISP) >> 16) + 1) * 8;

	if ((lvds->native_mode.panel_xres < 640) ||
	    (lvds->native_mode.panel_yres < 480)) {
		lvds->native_mode.panel_xres = 640;
		lvds->native_mode.panel_yres = 480;
	if ((lvds->native_mode.hdisplay < 640) ||
	    (lvds->native_mode.vdisplay < 480)) {
		lvds->native_mode.hdisplay = 640;
		lvds->native_mode.vdisplay = 480;
	}

	ppll_div_sel = RREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3;
@@ -846,8 +846,8 @@ static struct radeon_encoder_lvds *radeon_legacy_get_lvds_info_from_regs(struct
	lvds->panel_vcc_delay = 200;

	DRM_INFO("Panel info derived from registers\n");
	DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.panel_xres,
		 lvds->native_mode.panel_yres);
	DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.hdisplay,
		 lvds->native_mode.vdisplay);

	return lvds;
}
@@ -882,11 +882,11 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder

		DRM_INFO("Panel ID String: %s\n", stmp);

		lvds->native_mode.panel_xres = RBIOS16(lcd_info + 0x19);
		lvds->native_mode.panel_yres = RBIOS16(lcd_info + 0x1b);
		lvds->native_mode.hdisplay = RBIOS16(lcd_info + 0x19);
		lvds->native_mode.vdisplay = RBIOS16(lcd_info + 0x1b);

		DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.panel_xres,
			 lvds->native_mode.panel_yres);
		DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.hdisplay,
			 lvds->native_mode.vdisplay);

		lvds->panel_vcc_delay = RBIOS16(lcd_info + 0x2c);
		if (lvds->panel_vcc_delay > 2000 || lvds->panel_vcc_delay < 0)
@@ -944,27 +944,25 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder
			if (tmp == 0)
				break;

			if ((RBIOS16(tmp) == lvds->native_mode.panel_xres) &&
			if ((RBIOS16(tmp) == lvds->native_mode.hdisplay) &&
			    (RBIOS16(tmp + 2) ==
			     lvds->native_mode.panel_yres)) {
				lvds->native_mode.hblank =
				    (RBIOS16(tmp + 17) - RBIOS16(tmp + 19)) * 8;
				lvds->native_mode.hoverplus =
				    (RBIOS16(tmp + 21) - RBIOS16(tmp + 19) -
				     1) * 8;
				lvds->native_mode.hsync_width =
				    RBIOS8(tmp + 23) * 8;

				lvds->native_mode.vblank = (RBIOS16(tmp + 24) -
							    RBIOS16(tmp + 26));
				lvds->native_mode.voverplus =
				    ((RBIOS16(tmp + 28) & 0x7ff) -
				     RBIOS16(tmp + 26));
				lvds->native_mode.vsync_width =
				    ((RBIOS16(tmp + 28) & 0xf800) >> 11);
				lvds->native_mode.dotclock =
				    RBIOS16(tmp + 9) * 10;
			     lvds->native_mode.vdisplay)) {
				lvds->native_mode.htotal = RBIOS16(tmp + 17) * 8;
				lvds->native_mode.hsync_start = RBIOS16(tmp + 21) * 8;
				lvds->native_mode.hsync_end = (RBIOS8(tmp + 23) +
							       RBIOS16(tmp + 21)) * 8;

				lvds->native_mode.vtotal = RBIOS16(tmp + 24);
				lvds->native_mode.vsync_start = RBIOS16(tmp + 28) & 0x7ff;
				lvds->native_mode.vsync_end =
					((RBIOS16(tmp + 28) & 0xf800) >> 11) +
					(RBIOS16(tmp + 28) & 0x7ff);

				lvds->native_mode.clock = RBIOS16(tmp + 9) * 10;
				lvds->native_mode.flags = 0;
				/* set crtc values */
				drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V);

			}
		}
	} else {
+19 −36
Original line number Diff line number Diff line
@@ -178,25 +178,13 @@ static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encode
	struct drm_device *dev = encoder->dev;
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
	struct drm_display_mode *mode = NULL;
	struct radeon_native_mode *native_mode = &radeon_encoder->native_mode;
	struct drm_display_mode *native_mode = &radeon_encoder->native_mode;

	if (native_mode->panel_xres != 0 &&
	    native_mode->panel_yres != 0 &&
	    native_mode->dotclock != 0) {
	if (native_mode->hdisplay != 0 &&
	    native_mode->vdisplay != 0 &&
	    native_mode->clock != 0) {
		mode = drm_mode_create(dev);

		mode->hdisplay = native_mode->panel_xres;
		mode->vdisplay = native_mode->panel_yres;

		mode->htotal = mode->hdisplay + native_mode->hblank;
		mode->hsync_start = mode->hdisplay + native_mode->hoverplus;
		mode->hsync_end = mode->hsync_start + native_mode->hsync_width;
		mode->vtotal = mode->vdisplay + native_mode->vblank;
		mode->vsync_start = mode->vdisplay + native_mode->voverplus;
		mode->vsync_end = mode->vsync_start + native_mode->vsync_width;
		mode->clock = native_mode->dotclock;
		mode->flags = 0;

		*mode = *native_mode;
		mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
		drm_mode_set_name(mode);

@@ -210,7 +198,7 @@ static void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_conn
	struct drm_device *dev = encoder->dev;
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
	struct drm_display_mode *mode = NULL;
	struct radeon_native_mode *native_mode = &radeon_encoder->native_mode;
	struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
	int i;
	struct mode_size {
		int w;
@@ -237,10 +225,10 @@ static void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_conn

	for (i = 0; i < 17; i++) {
		if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
			if (common_modes[i].w > native_mode->panel_xres ||
			    common_modes[i].h > native_mode->panel_yres ||
			    (common_modes[i].w == native_mode->panel_xres &&
			     common_modes[i].h == native_mode->panel_yres))
			if (common_modes[i].w > native_mode->hdisplay ||
			    common_modes[i].h > native_mode->vdisplay ||
			    (common_modes[i].w == native_mode->hdisplay &&
			     common_modes[i].h == native_mode->vdisplay))
				continue;
		}
		if (common_modes[i].w < 320 || common_modes[i].h < 200)
@@ -344,28 +332,23 @@ 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;
	struct drm_display_mode *native_mode = &radeon_encoder->native_mode;

	/* Try to get native mode details from EDID if necessary */
	if (!native_mode->dotclock) {
	if (!native_mode->clock) {
		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;
			if (mode->hdisplay == native_mode->hdisplay &&
			    mode->vdisplay == native_mode->vdisplay) {
				*native_mode = *mode;
				drm_mode_set_crtcinfo(native_mode, CRTC_INTERLACE_HALVE_V);
				DRM_INFO("Determined LVDS native mode details from EDID\n");
				break;
			}
		}
	}
	if (!native_mode->dotclock) {
	if (!native_mode->clock) {
		DRM_INFO("No LVDS native mode details, disabling RMX\n");
		radeon_encoder->rmx_type = RMX_OFF;
	}
@@ -420,10 +403,10 @@ static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connec

	if (encoder) {
		struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
		struct radeon_native_mode *native_mode = &radeon_encoder->native_mode;
		struct drm_display_mode *native_mode = &radeon_encoder->native_mode;

		/* check if panel is valid */
		if (native_mode->panel_xres >= 320 && native_mode->panel_yres >= 240)
		if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240)
			ret = connector_status_connected;

	}
+3 −3
Original line number Diff line number Diff line
@@ -761,7 +761,7 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
			radeon_crtc->rmx_type = radeon_encoder->rmx_type;
			memcpy(&radeon_crtc->native_mode,
				&radeon_encoder->native_mode,
				sizeof(struct radeon_native_mode));
				sizeof(struct drm_display_mode));
			first = false;
		} else {
			if (radeon_crtc->rmx_type != radeon_encoder->rmx_type) {
@@ -779,10 +779,10 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
	if (radeon_crtc->rmx_type != RMX_OFF) {
		fixed20_12 a, b;
		a.full = rfixed_const(crtc->mode.vdisplay);
		b.full = rfixed_const(radeon_crtc->native_mode.panel_xres);
		b.full = rfixed_const(radeon_crtc->native_mode.hdisplay);
		radeon_crtc->vsc.full = rfixed_div(a, b);
		a.full = rfixed_const(crtc->mode.hdisplay);
		b.full = rfixed_const(radeon_crtc->native_mode.panel_yres);
		b.full = rfixed_const(radeon_crtc->native_mode.vdisplay);
		radeon_crtc->hsc.full = rfixed_div(a, b);
	} else {
		radeon_crtc->vsc.full = rfixed_const(1);
+8 −42
Original line number Diff line number Diff line
@@ -171,49 +171,15 @@ void radeon_rmx_mode_fixup(struct drm_encoder *encoder,
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
	struct drm_device *dev = encoder->dev;
	struct radeon_device *rdev = dev->dev_private;
	struct radeon_native_mode *native_mode = &radeon_encoder->native_mode;
	struct drm_display_mode *native_mode = &radeon_encoder->native_mode;

	if (mode->hdisplay < native_mode->panel_xres ||
	    mode->vdisplay < native_mode->panel_yres) {
		if (ASIC_IS_AVIVO(rdev)) {
			adjusted_mode->hdisplay = native_mode->panel_xres;
			adjusted_mode->vdisplay = native_mode->panel_yres;
			adjusted_mode->htotal = native_mode->panel_xres + native_mode->hblank;
			adjusted_mode->hsync_start = native_mode->panel_xres + native_mode->hoverplus;
			adjusted_mode->hsync_end = adjusted_mode->hsync_start + native_mode->hsync_width;
			adjusted_mode->vtotal = native_mode->panel_yres + native_mode->vblank;
			adjusted_mode->vsync_start = native_mode->panel_yres + native_mode->voverplus;
			adjusted_mode->vsync_end = adjusted_mode->vsync_start + native_mode->vsync_width;
			/* update crtc values */
			drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
			/* adjust crtc values */
			adjusted_mode->crtc_hdisplay = native_mode->panel_xres;
			adjusted_mode->crtc_vdisplay = native_mode->panel_yres;
			adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + native_mode->hblank;
			adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + native_mode->hoverplus;
			adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + native_mode->hsync_width;
			adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + native_mode->vblank;
			adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + native_mode->voverplus;
			adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + native_mode->vsync_width;
		} else {
			adjusted_mode->htotal = native_mode->panel_xres + native_mode->hblank;
			adjusted_mode->hsync_start = native_mode->panel_xres + native_mode->hoverplus;
			adjusted_mode->hsync_end = adjusted_mode->hsync_start + native_mode->hsync_width;
			adjusted_mode->vtotal = native_mode->panel_yres + native_mode->vblank;
			adjusted_mode->vsync_start = native_mode->panel_yres + native_mode->voverplus;
			adjusted_mode->vsync_end = adjusted_mode->vsync_start + native_mode->vsync_width;
			/* update crtc values */
			drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
			/* adjust crtc values */
			adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + native_mode->hblank;
			adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + native_mode->hoverplus;
			adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + native_mode->hsync_width;
			adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + native_mode->vblank;
			adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + native_mode->voverplus;
			adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + native_mode->vsync_width;
		}
		adjusted_mode->flags = native_mode->flags;
		adjusted_mode->clock = native_mode->dotclock;
	if (mode->hdisplay < native_mode->hdisplay ||
	    mode->vdisplay < native_mode->vdisplay) {
		*adjusted_mode = *native_mode;
		if (!ASIC_IS_AVIVO(rdev)) {
			adjusted_mode->hdisplay = mode->hdisplay;
			adjusted_mode->vdisplay = mode->vdisplay;
		}
	}
}

Loading