From mboxrd@z Thu Jan 1 00:00:00 1970 From: Egbert Eich Subject: Re: [PATCH 2/2] drm/ast: Add reduced/non-reduced mode parsing for wide screen mode Date: Fri, 22 Aug 2014 17:28:23 +0200 Message-ID: <21495.24983.475258.133171@linux-qknr.fritz.box> References: <1408676418-29890-1-git-send-email-yc_chen@aspeedtech.com> <1408676418-29890-2-git-send-email-yc_chen@aspeedtech.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from mx2.suse.de (cantor2.suse.de [195.135.220.15]) by gabe.freedesktop.org (Postfix) with ESMTP id E1FE96E3AA for ; Fri, 22 Aug 2014 08:28:46 -0700 (PDT) In-Reply-To: yc_chen@aspeedtech.com wrote on Friday, 22 August 2014 at 11:00:18 +0800 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: "Y.C. Chen" Cc: airlied@redhat.com, dri-devel@lists.freedesktop.org, eich@suse.com List-Id: dri-devel@lists.freedesktop.org Hi YC, Y.C. Chen writes: > From: "Y.C. Chen" > > Signed-off-by: Y.C. Chen > --- > drivers/gpu/drm/ast/ast_mode.c | 32 +++++++++++++++++++++++------- > drivers/gpu/drm/ast/ast_tables.h | 42 ++++++++++++++++++++++++---------------- > 2 files changed, 50 insertions(+), 24 deletions(-) > > diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c > index 5389350..5533920 100644 > --- a/drivers/gpu/drm/ast/ast_mode.c > +++ b/drivers/gpu/drm/ast/ast_mode.c > @@ -141,14 +141,30 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo > } > > refresh_rate = drm_mode_vrefresh(mode); > - while (vbios_mode->enh_table->refresh_rate < refresh_rate) { > - vbios_mode->enh_table++; > - if ((vbios_mode->enh_table->refresh_rate > refresh_rate) || > - (vbios_mode->enh_table->refresh_rate == 0xff)) { > + do { > + if ((vbios_mode->enh_table->flags & WideScreenMode) && > + (((mode->flags & DRM_MODE_FLAG_NVSYNC) && > + (vbios_mode->enh_table->flags & PVSync)) || > + ((mode->flags & DRM_MODE_FLAG_PVSYNC) && > + (vbios_mode->enh_table->flags & NVSync)) || > + ((mode->flags & DRM_MODE_FLAG_NHSYNC) && > + (vbios_mode->enh_table->flags & PHSync)) || > + ((mode->flags & DRM_MODE_FLAG_PHSYNC) && > + (vbios_mode->enh_table->flags & NHSync)))) { > + vbios_mode->enh_table++; > + continue; > + } > + if (vbios_mode->enh_table->refresh_rate < refresh_rate) { > + vbios_mode->enh_table++; > + } > + if ((vbios_mode->enh_table->refresh_rate_index > 1) && > + (vbios_mode->enh_table->refresh_rate > refresh_rate)) { > vbios_mode->enh_table--; > break; > } > - } > + } while (vbios_mode->enh_table->refresh_rate != 0xff); > + if (vbios_mode->enh_table->refresh_rate == 0xff) > + vbios_mode->enh_table--; I've tested this and experimented around a bit and came up with code like this: bool check_sync; struct ast_vbios_enhtable *best = NULL; [..] refresh_rate = drm_mode_vrefresh(mode); check_sync = vbios_mode->enh_table->flags & WideScreenMode; do { struct ast_vbios_enhtable *loop = best = vbios_mode->enh_table; while (loop->refresh_rate != 0xff) { if ((check_sync) && (((mode->flags & DRM_MODE_FLAG_NVSYNC) && (loop->flags & PVSync)) || ((mode->flags & DRM_MODE_FLAG_PVSYNC) && (loop->flags & NVSync)) || ((mode->flags & DRM_MODE_FLAG_NHSYNC) && (loop->flags & PHSync)) || ((mode->flags & DRM_MODE_FLAG_PHSYNC) && (loop->flags & NHSync)))) { loop++; continue; } if (loop->refresh_rate <= refresh_rate && loop->refresh_rate > best->refresh_rate) best = loop; loop++; } if (!check_sync) break; check_sync = 0; } while (1); if (!best) return false; vbios_mode->enh_table = best; This way the code doesn't make the assumption that the refresh rates are in ascending order and we can map the sync polarities for all modes, not just the wide screen ones. > > hborder = (vbios_mode->enh_table->flags & HBorder) ? 8 : 0; > vborder = (vbios_mode->enh_table->flags & VBorder) ? 8 : 0; > @@ -419,8 +435,10 @@ static void ast_set_sync_reg(struct drm_device *dev, struct drm_display_mode *mo > struct ast_private *ast = dev->dev_private; > u8 jreg; > > - jreg = ast_io_read8(ast, AST_IO_MISC_PORT_READ); > - jreg |= (vbios_mode->enh_table->flags & SyncNN); > + jreg = ast_io_read8(ast, AST_IO_MISC_PORT_READ); > + jreg &= 0xC0; This should be: jreg &= ~0xC0U; > + if (vbios_mode->enh_table->flags & NVSync) jreg |= 0x80; > + if (vbios_mode->enh_table->flags & NHSync) jreg |= 0x40; > ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg); > } > Cheers, Egbert.