summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/ast/ast_mode.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/ast/ast_mode.c')
-rw-r--r--drivers/gpu/drm/ast/ast_mode.c54
1 files changed, 38 insertions, 16 deletions
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index e26c98f51eb4..47b78e52691c 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -79,12 +79,13 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
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;
+ const struct ast_vbios_enhtable *best = NULL;
u32 hborder, vborder;
bool check_sync;
- struct ast_vbios_enhtable *best = NULL;
- switch (crtc->primary->fb->bits_per_pixel) {
+ switch (fb->format->cpp[0] * 8) {
case 8:
vbios_mode->std_table = &vbios_stdtable[VGAModeIndex];
color_index = VGAModeIndex - 1;
@@ -146,7 +147,7 @@ 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 {
- struct ast_vbios_enhtable *loop = vbios_mode->enh_table;
+ const struct ast_vbios_enhtable *loop = vbios_mode->enh_table;
while (loop->refresh_rate != 0xff) {
if ((check_sync) &&
@@ -207,7 +208,8 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
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, crtc->primary->fb->bits_per_pixel);
+ 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);
@@ -225,7 +227,7 @@ static void ast_set_std_reg(struct drm_crtc *crtc, struct drm_display_mode *mode
struct ast_vbios_mode_info *vbios_mode)
{
struct ast_private *ast = crtc->dev->dev_private;
- struct ast_vbios_stdtable *stdtable;
+ const struct ast_vbios_stdtable *stdtable;
u32 i;
u8 jreg;
@@ -271,7 +273,11 @@ static void ast_set_crtc_reg(struct drm_crtc *crtc, struct drm_display_mode *mod
{
struct ast_private *ast = crtc->dev->dev_private;
u8 jreg05 = 0, jreg07 = 0, jreg09 = 0, jregAC = 0, jregAD = 0, jregAE = 0;
- u16 temp;
+ u16 temp, precache = 0;
+
+ if ((ast->chip == AST2500) &&
+ (vbios_mode->enh_table->flags & AST2500PreCatchCRT))
+ precache = 40;
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00);
@@ -297,12 +303,12 @@ static void ast_set_crtc_reg(struct drm_crtc *crtc, struct drm_display_mode *mod
jregAD |= 0x01; /* HBE D[5] */
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x03, 0xE0, (temp & 0x1f));
- temp = (mode->crtc_hsync_start >> 3) - 1;
+ temp = ((mode->crtc_hsync_start-precache) >> 3) - 1;
if (temp & 0x100)
jregAC |= 0x40; /* HRS D[5] */
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x04, 0x00, temp);
- temp = ((mode->crtc_hsync_end >> 3) - 1) & 0x3f;
+ temp = (((mode->crtc_hsync_end-precache) >> 3) - 1) & 0x3f;
if (temp & 0x20)
jregAD |= 0x04; /* HRE D[5] */
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x05, 0x60, (u8)((temp & 0x1f) | jreg05));
@@ -363,16 +369,22 @@ static void ast_set_crtc_reg(struct drm_crtc *crtc, struct drm_display_mode *mod
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x09, 0xdf, jreg09);
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAE, 0x00, (jregAE | 0x80));
+ if (precache)
+ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x80);
+ else
+ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x00);
+
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x80);
}
static void ast_set_offset_reg(struct drm_crtc *crtc)
{
struct ast_private *ast = crtc->dev->dev_private;
+ const struct drm_framebuffer *fb = crtc->primary->fb;
u16 offset;
- offset = crtc->primary->fb->pitches[0] >> 3;
+ offset = fb->pitches[0] >> 3;
ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x13, (offset & 0xff));
ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xb0, (offset >> 8) & 0x3f);
}
@@ -381,23 +393,28 @@ static void ast_set_dclk_reg(struct drm_device *dev, struct drm_display_mode *mo
struct ast_vbios_mode_info *vbios_mode)
{
struct ast_private *ast = dev->dev_private;
- struct ast_vbios_dclk_info *clk_info;
+ const struct ast_vbios_dclk_info *clk_info;
- clk_info = &dclk_table[vbios_mode->enh_table->dclk_index];
+ if (ast->chip == AST2500)
+ clk_info = &dclk_table_ast2500[vbios_mode->enh_table->dclk_index];
+ else
+ clk_info = &dclk_table[vbios_mode->enh_table->dclk_index];
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc0, 0x00, clk_info->param1);
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc1, 0x00, clk_info->param2);
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xbb, 0x0f,
- (clk_info->param3 & 0x80) | ((clk_info->param3 & 0x3) << 4));
+ (clk_info->param3 & 0xc0) |
+ ((clk_info->param3 & 0x3) << 4));
}
static void ast_set_ext_reg(struct drm_crtc *crtc, struct drm_display_mode *mode,
struct ast_vbios_mode_info *vbios_mode)
{
struct ast_private *ast = crtc->dev->dev_private;
+ const struct drm_framebuffer *fb = crtc->primary->fb;
u8 jregA0 = 0, jregA3 = 0, jregA8 = 0;
- switch (crtc->primary->fb->bits_per_pixel) {
+ switch (fb->format->cpp[0] * 8) {
case 8:
jregA0 = 0x70;
jregA3 = 0x01;
@@ -421,7 +438,8 @@ static void ast_set_ext_reg(struct drm_crtc *crtc, struct drm_display_mode *mode
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa8, 0xfd, jregA8);
/* Set Threshold */
- if (ast->chip == AST2300 || ast->chip == AST2400) {
+ if (ast->chip == AST2300 || ast->chip == AST2400 ||
+ ast->chip == AST2500) {
ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x78);
ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x60);
} else if (ast->chip == AST2100 ||
@@ -452,7 +470,9 @@ static void ast_set_sync_reg(struct drm_device *dev, struct drm_display_mode *mo
static bool ast_set_dac_reg(struct drm_crtc *crtc, struct drm_display_mode *mode,
struct ast_vbios_mode_info *vbios_mode)
{
- switch (crtc->primary->fb->bits_per_pixel) {
+ const struct drm_framebuffer *fb = crtc->primary->fb;
+
+ switch (fb->format->cpp[0] * 8) {
case 8:
break;
default:
@@ -794,7 +814,9 @@ static int ast_mode_valid(struct drm_connector *connector,
if ((mode->hdisplay == 1600) && (mode->vdisplay == 900))
return MODE_OK;
- if ((ast->chip == AST2100) || (ast->chip == AST2200) || (ast->chip == AST2300) || (ast->chip == AST2400) || (ast->chip == AST1180)) {
+ if ((ast->chip == AST2100) || (ast->chip == AST2200) ||
+ (ast->chip == AST2300) || (ast->chip == AST2400) ||
+ (ast->chip == AST2500) || (ast->chip == AST1180)) {
if ((mode->hdisplay == 1920) && (mode->vdisplay == 1080))
return MODE_OK;