[PATCH 5/9] drm/ast: Split ast_set_vbios_mode_info()
Gerd Hoffmann
kraxel at redhat.com
Tue Nov 5 09:47:25 UTC 2019
On Mon, Oct 28, 2019 at 04:49:24PM +0100, Thomas Zimmermann wrote:
> The implementation of ast_set_vbios_mode() converts a DRM display mode
> and framebuffer into an adjusted mode and stores information for the
> video BIOS to several scratch regsiters.
>
> Here we split the function into individual functions that do the
> conversion, set the VBIOS mode information and format information.
> This makes it compatible with support for primary planes and atomic
> modesetting.
Acked-by: Gerd Hoffmann <kraxel at redhat.com>
>
> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
> ---
> drivers/gpu/drm/ast/ast_mode.c | 111 +++++++++++++++++++++------------
> 1 file changed, 72 insertions(+), 39 deletions(-)
>
> diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
> index 5feb687191e0..c4c9fca0f00c 100644
> --- a/drivers/gpu/drm/ast/ast_mode.c
> +++ b/drivers/gpu/drm/ast/ast_mode.c
> @@ -82,13 +82,12 @@ static void ast_crtc_load_lut(struct drm_crtc *crtc)
> ast_load_palette_index(ast, i, *r++ >> 8, *g++ >> 8, *b++ >> 8);
> }
>
> -static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mode *mode,
> +static bool ast_get_vbios_mode_info(const struct drm_framebuffer *fb,
> + const struct drm_display_mode *mode,
> struct drm_display_mode *adjusted_mode,
> struct ast_vbios_mode_info *vbios_mode)
> {
> - struct ast_private *ast = crtc->dev->dev_private;
> - const struct drm_framebuffer *fb = crtc->primary->fb;
> - u32 refresh_rate_index = 0, mode_id, color_index, refresh_rate;
> + u32 refresh_rate_index = 0, refresh_rate;
> const struct ast_vbios_enhtable *best = NULL;
> u32 hborder, vborder;
> bool check_sync;
> @@ -96,22 +95,19 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
> switch (fb->format->cpp[0] * 8) {
> case 8:
> vbios_mode->std_table = &vbios_stdtable[VGAModeIndex];
> - color_index = VGAModeIndex - 1;
> break;
> case 16:
> vbios_mode->std_table = &vbios_stdtable[HiCModeIndex];
> - color_index = HiCModeIndex;
> break;
> case 24:
> case 32:
> vbios_mode->std_table = &vbios_stdtable[TrueCModeIndex];
> - color_index = TrueCModeIndex;
> break;
> default:
> return false;
> }
>
> - switch (crtc->mode.crtc_hdisplay) {
> + switch (mode->crtc_hdisplay) {
> case 640:
> vbios_mode->enh_table = &res_640x480[refresh_rate_index];
> break;
> @@ -122,7 +118,7 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
> vbios_mode->enh_table = &res_1024x768[refresh_rate_index];
> break;
> case 1280:
> - if (crtc->mode.crtc_vdisplay == 800)
> + if (mode->crtc_vdisplay == 800)
> vbios_mode->enh_table = &res_1280x800[refresh_rate_index];
> else
> vbios_mode->enh_table = &res_1280x1024[refresh_rate_index];
> @@ -134,7 +130,7 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
> vbios_mode->enh_table = &res_1440x900[refresh_rate_index];
> break;
> case 1600:
> - if (crtc->mode.crtc_vdisplay == 900)
> + if (mode->crtc_vdisplay == 900)
> vbios_mode->enh_table = &res_1600x900[refresh_rate_index];
> else
> vbios_mode->enh_table = &res_1600x1200[refresh_rate_index];
> @@ -143,7 +139,7 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
> vbios_mode->enh_table = &res_1680x1050[refresh_rate_index];
> break;
> case 1920:
> - if (crtc->mode.crtc_vdisplay == 1080)
> + if (mode->crtc_vdisplay == 1080)
> vbios_mode->enh_table = &res_1920x1080[refresh_rate_index];
> else
> vbios_mode->enh_table = &res_1920x1200[refresh_rate_index];
> @@ -154,7 +150,8 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
>
> refresh_rate = drm_mode_vrefresh(mode);
> check_sync = vbios_mode->enh_table->flags & WideScreenMode;
> - do {
> +
> + while (1) {
> const struct ast_vbios_enhtable *loop = vbios_mode->enh_table;
>
> while (loop->refresh_rate != 0xff) {
> @@ -178,7 +175,8 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
> if (best || !check_sync)
> break;
> check_sync = 0;
> - } while (1);
> + }
> +
> if (best)
> vbios_mode->enh_table = best;
>
> @@ -203,34 +201,65 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
> vbios_mode->enh_table->vfp +
> vbios_mode->enh_table->vsync);
>
> - refresh_rate_index = vbios_mode->enh_table->refresh_rate_index;
> - mode_id = vbios_mode->enh_table->mode_id;
> + return true;
> +}
>
> - if (ast->chip == AST1180) {
> - /* TODO 1180 */
> - } else {
> - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8c, (u8)((color_index & 0xf) << 4));
> - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8d, refresh_rate_index & 0xff);
> - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff);
> -
> - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00);
> - if (vbios_mode->enh_table->flags & NewModeInfo) {
> - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8);
> - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92,
> - fb->format->cpp[0] * 8);
> - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, adjusted_mode->clock / 1000);
> - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, adjusted_mode->crtc_hdisplay);
> - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, adjusted_mode->crtc_hdisplay >> 8);
> -
> - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x96, adjusted_mode->crtc_vdisplay);
> - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x97, adjusted_mode->crtc_vdisplay >> 8);
> - }
> +static void ast_set_vbios_color_reg(struct drm_crtc *crtc,
> + const struct drm_framebuffer *fb,
> + const struct ast_vbios_mode_info *vbios_mode)
> +{
> + struct ast_private *ast = crtc->dev->dev_private;
> + u32 color_index;
> +
> + switch (fb->format->cpp[0]) {
> + case 1:
> + color_index = VGAModeIndex - 1;
> + break;
> + case 2:
> + color_index = HiCModeIndex;
> + break;
> + case 3:
> + case 4:
> + color_index = TrueCModeIndex;
> + default:
> + return;
> }
>
> - return true;
> + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8c, (u8)((color_index & 0x0f) << 4));
> +
> + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00);
> +
> + if (vbios_mode->enh_table->flags & NewModeInfo) {
> + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8);
> + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, fb->format->cpp[0] * 8);
> + }
> +}
> +
> +static void ast_set_vbios_mode_reg(struct drm_crtc *crtc,
> + const struct drm_display_mode *adjusted_mode,
> + const struct ast_vbios_mode_info *vbios_mode)
> +{
> + struct ast_private *ast = crtc->dev->dev_private;
> + u32 refresh_rate_index, mode_id;
> +
> + refresh_rate_index = vbios_mode->enh_table->refresh_rate_index;
> + mode_id = vbios_mode->enh_table->mode_id;
> +
> + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8d, refresh_rate_index & 0xff);
> + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff);
>
> + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00);
>
> + if (vbios_mode->enh_table->flags & NewModeInfo) {
> + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8);
> + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, adjusted_mode->clock / 1000);
> + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, adjusted_mode->crtc_hdisplay);
> + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, adjusted_mode->crtc_hdisplay >> 8);
> + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x96, adjusted_mode->crtc_vdisplay);
> + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x97, adjusted_mode->crtc_vdisplay >> 8);
> + }
> }
> +
> static void ast_set_std_reg(struct drm_crtc *crtc, struct drm_display_mode *mode,
> struct ast_vbios_mode_info *vbios_mode)
> {
> @@ -581,20 +610,24 @@ static int ast_crtc_mode_set(struct drm_crtc *crtc,
> {
> struct drm_device *dev = crtc->dev;
> struct ast_private *ast = crtc->dev->dev_private;
> + const struct drm_framebuffer *fb = crtc->primary->fb;
> struct ast_vbios_mode_info vbios_mode;
> - bool ret;
> + bool succ;
> +
> if (ast->chip == AST1180) {
> DRM_ERROR("AST 1180 modesetting not supported\n");
> return -EINVAL;
> }
>
> - ret = ast_get_vbios_mode_info(crtc, mode, adjusted_mode, &vbios_mode);
> - if (ret == false)
> + succ = ast_get_vbios_mode_info(fb, mode, adjusted_mode, &vbios_mode);
> + if (!succ)
> return -EINVAL;
> +
> ast_open_key(ast);
>
> + ast_set_vbios_color_reg(crtc, fb, &vbios_mode);
> + ast_set_vbios_mode_reg(crtc, adjusted_mode, &vbios_mode);
> ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06);
> -
> ast_set_std_reg(crtc, adjusted_mode, &vbios_mode);
> ast_set_crtc_reg(crtc, adjusted_mode, &vbios_mode);
> ast_set_offset_reg(crtc);
> --
> 2.23.0
>
More information about the dri-devel
mailing list