Skip to content

Commit

Permalink
drm/radeon/kms: use drm_mode directly for panel modes
Browse files Browse the repository at this point in the history
This reduces the number of mode format conversions needed
and makes native panel mode support cleaner.

Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
  • Loading branch information
Alex Deucher authored and Dave Airlie committed Oct 12, 2009
1 parent 5a9bcac commit de2103e
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 159 deletions.
32 changes: 17 additions & 15 deletions drivers/gpu/drm/radeon/radeon_atombios.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
le16_to_cpu(lvds_info->info.sLCDTiming.usHBlanking_Time);
lvds->native_mode.hoverplus =
le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncOffset);
lvds->native_mode.hsync_width =
le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncWidth);
lvds->native_mode.vblank =
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 =
le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth);
lvds->native_mode.htotal = lvds->native_mode.hdisplay +
le16_to_cpu(lvds_info->info.sLCDTiming.usHBlanking_Time);
lvds->native_mode.hsync_start = lvds->native_mode.hdisplay +
le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncOffset);
lvds->native_mode.hsync_end = lvds->native_mode.hsync_start +
le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncWidth);
lvds->native_mode.vtotal = lvds->native_mode.vdisplay +
le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time);
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;
}
Expand Down
64 changes: 31 additions & 33 deletions drivers/gpu/drm/radeon/radeon_combios.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 {
Expand Down
55 changes: 19 additions & 36 deletions drivers/gpu/drm/radeon/radeon_connectors.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;

}
Expand Down
6 changes: 3 additions & 3 deletions drivers/gpu/drm/radeon/radeon_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
Expand Down
50 changes: 8 additions & 42 deletions drivers/gpu/drm/radeon/radeon_encoders.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

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;
struct drm_display_mode *native_mode = &radeon_encoder->native_mode;

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;
}
adjusted_mode->flags = native_mode->flags;
adjusted_mode->clock = native_mode->dotclock;
}
}

Expand Down
Loading

0 comments on commit de2103e

Please sign in to comment.