[PATCH 2/2] drm/ast: Add reduced/non-reduced mode parsing for wide screen mode
YC Chen
yc_chen at aspeedtech.com
Fri Aug 22 08:57:19 PDT 2014
Hi Egbert,
Thanks for your comment. The modification is great. If possible, could you create a new patch to patch my original patch?
Regards,
Y.C. Chen
"Egbert Eich" <eich at freedesktop.org> 於 2014/8/22 下午11:29 寫道:
>
> Hi YC,
>
> Y.C. Chen writes:
>> From: "Y.C. Chen" <yc_chen at aspeedtech.com>
>>
>> Signed-off-by: Y.C. Chen <yc_chen at aspeedtech.com>
>> ---
>> 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.
More information about the dri-devel
mailing list