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@xxxxxxxxxx> > > Signed-off-by: Thomas Zimmermann <tzimmermann@xxxxxxx> > --- > 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 > _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel