[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