diff options
Diffstat (limited to 'drivers/gpu/drm/ast')
| -rw-r--r-- | drivers/gpu/drm/ast/ast_2000.c | 9 | ||||
| -rw-r--r-- | drivers/gpu/drm/ast/ast_2100.c | 9 | ||||
| -rw-r--r-- | drivers/gpu/drm/ast/ast_2200.c | 9 | ||||
| -rw-r--r-- | drivers/gpu/drm/ast/ast_2300.c | 9 | ||||
| -rw-r--r-- | drivers/gpu/drm/ast/ast_2400.c | 9 | ||||
| -rw-r--r-- | drivers/gpu/drm/ast/ast_2500.c | 10 | ||||
| -rw-r--r-- | drivers/gpu/drm/ast/ast_2600.c | 11 | ||||
| -rw-r--r-- | drivers/gpu/drm/ast/ast_drv.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/ast/ast_drv.h | 27 | ||||
| -rw-r--r-- | drivers/gpu/drm/ast/ast_mode.c | 46 |
10 files changed, 103 insertions, 40 deletions
diff --git a/drivers/gpu/drm/ast/ast_2000.c b/drivers/gpu/drm/ast/ast_2000.c index 03b0dcea43d1..fa3bc23ce098 100644 --- a/drivers/gpu/drm/ast/ast_2000.c +++ b/drivers/gpu/drm/ast/ast_2000.c @@ -211,6 +211,11 @@ void ast_2000_detect_tx_chip(struct ast_device *ast, bool need_post) __ast_device_set_tx_chip(ast, tx_chip); } +static const struct ast_device_quirks ast_2000_device_quirks = { + .crtc_mem_req_threshold_low = 31, + .crtc_mem_req_threshold_high = 47, +}; + struct drm_device *ast_2000_device_create(struct pci_dev *pdev, const struct drm_driver *drv, enum ast_chip chip, @@ -228,7 +233,9 @@ struct drm_device *ast_2000_device_create(struct pci_dev *pdev, return ERR_CAST(ast); dev = &ast->base; - ast_device_init(ast, chip, config_mode, regs, ioregs); + ast_device_init(ast, chip, config_mode, regs, ioregs, &ast_2000_device_quirks); + + ast->dclk_table = ast_2000_dclk_table; ast_2000_detect_tx_chip(ast, need_post); diff --git a/drivers/gpu/drm/ast/ast_2100.c b/drivers/gpu/drm/ast/ast_2100.c index 540972daec52..05aeb0624d41 100644 --- a/drivers/gpu/drm/ast/ast_2100.c +++ b/drivers/gpu/drm/ast/ast_2100.c @@ -432,6 +432,11 @@ static void ast_2100_detect_widescreen(struct ast_device *ast) ast->support_wuxga = true; } +static const struct ast_device_quirks ast_2100_device_quirks = { + .crtc_mem_req_threshold_low = 47, + .crtc_mem_req_threshold_high = 63, +}; + struct drm_device *ast_2100_device_create(struct pci_dev *pdev, const struct drm_driver *drv, enum ast_chip chip, @@ -449,7 +454,9 @@ struct drm_device *ast_2100_device_create(struct pci_dev *pdev, return ERR_CAST(ast); dev = &ast->base; - ast_device_init(ast, chip, config_mode, regs, ioregs); + ast_device_init(ast, chip, config_mode, regs, ioregs, &ast_2100_device_quirks); + + ast->dclk_table = ast_2000_dclk_table; ast_2000_detect_tx_chip(ast, need_post); diff --git a/drivers/gpu/drm/ast/ast_2200.c b/drivers/gpu/drm/ast/ast_2200.c index 4795966dc2a7..b64345d11ffa 100644 --- a/drivers/gpu/drm/ast/ast_2200.c +++ b/drivers/gpu/drm/ast/ast_2200.c @@ -43,6 +43,11 @@ static void ast_2200_detect_widescreen(struct ast_device *ast) ast->support_wuxga = true; } +static const struct ast_device_quirks ast_2200_device_quirks = { + .crtc_mem_req_threshold_low = 47, + .crtc_mem_req_threshold_high = 63, +}; + struct drm_device *ast_2200_device_create(struct pci_dev *pdev, const struct drm_driver *drv, enum ast_chip chip, @@ -60,7 +65,9 @@ struct drm_device *ast_2200_device_create(struct pci_dev *pdev, return ERR_CAST(ast); dev = &ast->base; - ast_device_init(ast, chip, config_mode, regs, ioregs); + ast_device_init(ast, chip, config_mode, regs, ioregs, &ast_2200_device_quirks); + + ast->dclk_table = ast_2000_dclk_table; ast_2000_detect_tx_chip(ast, need_post); diff --git a/drivers/gpu/drm/ast/ast_2300.c b/drivers/gpu/drm/ast/ast_2300.c index d1d63e58f3d6..5f50d9f91ffd 100644 --- a/drivers/gpu/drm/ast/ast_2300.c +++ b/drivers/gpu/drm/ast/ast_2300.c @@ -1407,6 +1407,11 @@ static void ast_2300_detect_widescreen(struct ast_device *ast) ast->support_wuxga = true; } +static const struct ast_device_quirks ast_2300_device_quirks = { + .crtc_mem_req_threshold_low = 96, + .crtc_mem_req_threshold_high = 120, +}; + struct drm_device *ast_2300_device_create(struct pci_dev *pdev, const struct drm_driver *drv, enum ast_chip chip, @@ -1424,7 +1429,9 @@ struct drm_device *ast_2300_device_create(struct pci_dev *pdev, return ERR_CAST(ast); dev = &ast->base; - ast_device_init(ast, chip, config_mode, regs, ioregs); + ast_device_init(ast, chip, config_mode, regs, ioregs, &ast_2300_device_quirks); + + ast->dclk_table = ast_2000_dclk_table; ast_2300_detect_tx_chip(ast); diff --git a/drivers/gpu/drm/ast/ast_2400.c b/drivers/gpu/drm/ast/ast_2400.c index 596338ea22f4..2e6befd24f91 100644 --- a/drivers/gpu/drm/ast/ast_2400.c +++ b/drivers/gpu/drm/ast/ast_2400.c @@ -44,6 +44,11 @@ static void ast_2400_detect_widescreen(struct ast_device *ast) ast->support_wuxga = true; } +static const struct ast_device_quirks ast_2400_device_quirks = { + .crtc_mem_req_threshold_low = 96, + .crtc_mem_req_threshold_high = 120, +}; + struct drm_device *ast_2400_device_create(struct pci_dev *pdev, const struct drm_driver *drv, enum ast_chip chip, @@ -61,7 +66,9 @@ struct drm_device *ast_2400_device_create(struct pci_dev *pdev, return ERR_CAST(ast); dev = &ast->base; - ast_device_init(ast, chip, config_mode, regs, ioregs); + ast_device_init(ast, chip, config_mode, regs, ioregs, &ast_2400_device_quirks); + + ast->dclk_table = ast_2000_dclk_table; ast_2300_detect_tx_chip(ast); diff --git a/drivers/gpu/drm/ast/ast_2500.c b/drivers/gpu/drm/ast/ast_2500.c index 2c56db644f06..2a52af0ded56 100644 --- a/drivers/gpu/drm/ast/ast_2500.c +++ b/drivers/gpu/drm/ast/ast_2500.c @@ -618,6 +618,12 @@ static void ast_2500_detect_widescreen(struct ast_device *ast) ast->support_wuxga = true; } +static const struct ast_device_quirks ast_2500_device_quirks = { + .crtc_mem_req_threshold_low = 96, + .crtc_mem_req_threshold_high = 120, + .crtc_hsync_precatch_needed = true, +}; + struct drm_device *ast_2500_device_create(struct pci_dev *pdev, const struct drm_driver *drv, enum ast_chip chip, @@ -635,7 +641,9 @@ struct drm_device *ast_2500_device_create(struct pci_dev *pdev, return ERR_CAST(ast); dev = &ast->base; - ast_device_init(ast, chip, config_mode, regs, ioregs); + ast_device_init(ast, chip, config_mode, regs, ioregs, &ast_2500_device_quirks); + + ast->dclk_table = ast_2500_dclk_table; ast_2300_detect_tx_chip(ast); diff --git a/drivers/gpu/drm/ast/ast_2600.c b/drivers/gpu/drm/ast/ast_2600.c index 30490c473797..dee78fd5b022 100644 --- a/drivers/gpu/drm/ast/ast_2600.c +++ b/drivers/gpu/drm/ast/ast_2600.c @@ -59,6 +59,13 @@ static void ast_2600_detect_widescreen(struct ast_device *ast) ast->support_wuxga = true; } +static const struct ast_device_quirks ast_2600_device_quirks = { + .crtc_mem_req_threshold_low = 160, + .crtc_mem_req_threshold_high = 224, + .crtc_hsync_precatch_needed = true, + .crtc_hsync_add4_needed = true, +}; + struct drm_device *ast_2600_device_create(struct pci_dev *pdev, const struct drm_driver *drv, enum ast_chip chip, @@ -76,7 +83,9 @@ struct drm_device *ast_2600_device_create(struct pci_dev *pdev, return ERR_CAST(ast); dev = &ast->base; - ast_device_init(ast, chip, config_mode, regs, ioregs); + ast_device_init(ast, chip, config_mode, regs, ioregs, &ast_2600_device_quirks); + + ast->dclk_table = ast_2500_dclk_table; ast_2300_detect_tx_chip(ast); diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index a89735c6a462..b9a9b050b546 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -51,8 +51,10 @@ void ast_device_init(struct ast_device *ast, enum ast_chip chip, enum ast_config_mode config_mode, void __iomem *regs, - void __iomem *ioregs) + void __iomem *ioregs, + const struct ast_device_quirks *quirks) { + ast->quirks = quirks; ast->chip = chip; ast->config_mode = config_mode; ast->regs = regs; diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 35c476c85b9a..7be36a358e74 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -164,9 +164,31 @@ to_ast_connector(struct drm_connector *connector) * Device */ +struct ast_device_quirks { + /* + * CRTC memory request threshold + */ + unsigned char crtc_mem_req_threshold_low; + unsigned char crtc_mem_req_threshold_high; + + /* + * Adjust hsync values to load next scanline early. Signalled + * by AST2500PreCatchCRT in VBIOS mode flags. + */ + bool crtc_hsync_precatch_needed; + + /* + * Workaround for modes with HSync Time that is not a multiple + * of 8 (e.g., 1920x1080@60Hz, HSync +44 pixels). + */ + bool crtc_hsync_add4_needed; +}; + struct ast_device { struct drm_device base; + const struct ast_device_quirks *quirks; + void __iomem *regs; void __iomem *ioregs; void __iomem *dp501_fw_buf; @@ -174,6 +196,8 @@ struct ast_device { enum ast_config_mode config_mode; enum ast_chip chip; + const struct ast_vbios_dclk_info *dclk_table; + void __iomem *vram; unsigned long vram_base; unsigned long vram_size; @@ -412,7 +436,8 @@ void ast_device_init(struct ast_device *ast, enum ast_chip chip, enum ast_config_mode config_mode, void __iomem *regs, - void __iomem *ioregs); + void __iomem *ioregs, + const struct ast_device_quirks *quirks); void __ast_device_set_tx_chip(struct ast_device *ast, enum ast_tx_chip tx_chip); /* ast_2000.c */ diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 9b6a7c54fbb5..9ce874dba69c 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -241,16 +241,15 @@ static void ast_set_std_reg(struct ast_device *ast, ast_set_index_reg(ast, AST_IO_VGAGRI, i, stdtable->gr[i]); } -static void ast_set_crtc_reg(struct ast_device *ast, - struct drm_display_mode *mode, +static void ast_set_crtc_reg(struct ast_device *ast, struct drm_display_mode *mode, const struct ast_vbios_enhtable *vmode) { u8 jreg05 = 0, jreg07 = 0, jreg09 = 0, jregAC = 0, jregAD = 0, jregAE = 0; - u16 temp, precache = 0; + u16 temp; + unsigned char crtc_hsync_precatch = 0; - if ((IS_AST_GEN6(ast) || IS_AST_GEN7(ast)) && - (vmode->flags & AST2500PreCatchCRT)) - precache = 40; + if (ast->quirks->crtc_hsync_precatch_needed && (vmode->flags & AST2500PreCatchCRT)) + crtc_hsync_precatch = 40; ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x11, 0x7f, 0x00); @@ -276,12 +275,12 @@ static void ast_set_crtc_reg(struct ast_device *ast, jregAD |= 0x01; /* HBE D[5] */ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x03, 0xE0, (temp & 0x1f)); - temp = ((mode->crtc_hsync_start-precache) >> 3) - 1; + temp = ((mode->crtc_hsync_start - crtc_hsync_precatch) >> 3) - 1; if (temp & 0x100) jregAC |= 0x40; /* HRS D[5] */ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x04, 0x00, temp); - temp = (((mode->crtc_hsync_end-precache) >> 3) - 1) & 0x3f; + temp = (((mode->crtc_hsync_end - crtc_hsync_precatch) >> 3) - 1) & 0x3f; if (temp & 0x20) jregAD |= 0x04; /* HRE D[5] */ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x05, 0x60, (u8)((temp & 0x1f) | jreg05)); @@ -289,8 +288,7 @@ static void ast_set_crtc_reg(struct ast_device *ast, ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xAC, 0x00, jregAC); ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xAD, 0x00, jregAD); - // Workaround for HSync Time non octave pixels (1920x1080@60Hz HSync 44 pixels); - if (IS_AST_GEN7(ast) && (mode->crtc_vdisplay == 1080)) + if (ast->quirks->crtc_hsync_add4_needed && mode->crtc_vdisplay == 1080) ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xFC, 0xFD, 0x02); else ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xFC, 0xFD, 0x00); @@ -348,7 +346,7 @@ static void ast_set_crtc_reg(struct ast_device *ast, ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x09, 0xdf, jreg09); ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xAE, 0x00, (jregAE | 0x80)); - if (precache) + if (crtc_hsync_precatch) ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0x3f, 0x80); else ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0x3f, 0x00); @@ -370,12 +368,7 @@ static void ast_set_dclk_reg(struct ast_device *ast, struct drm_display_mode *mode, const struct ast_vbios_enhtable *vmode) { - const struct ast_vbios_dclk_info *clk_info; - - if (IS_AST_GEN6(ast) || IS_AST_GEN7(ast)) - clk_info = &ast_2500_dclk_table[vmode->dclk_index]; - else - clk_info = &ast_2000_dclk_table[vmode->dclk_index]; + const struct ast_vbios_dclk_info *clk_info = &ast->dclk_table[vmode->dclk_index]; ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xc0, 0x00, clk_info->param1); ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xc1, 0x00, clk_info->param2); @@ -415,20 +408,11 @@ static void ast_set_color_reg(struct ast_device *ast, static void ast_set_crtthd_reg(struct ast_device *ast) { - /* Set Threshold */ - if (IS_AST_GEN7(ast)) { - ast_set_index_reg(ast, AST_IO_VGACRI, 0xa7, 0xe0); - ast_set_index_reg(ast, AST_IO_VGACRI, 0xa6, 0xa0); - } else if (IS_AST_GEN6(ast) || IS_AST_GEN5(ast) || IS_AST_GEN4(ast)) { - ast_set_index_reg(ast, AST_IO_VGACRI, 0xa7, 0x78); - ast_set_index_reg(ast, AST_IO_VGACRI, 0xa6, 0x60); - } else if (IS_AST_GEN3(ast) || IS_AST_GEN2(ast)) { - ast_set_index_reg(ast, AST_IO_VGACRI, 0xa7, 0x3f); - ast_set_index_reg(ast, AST_IO_VGACRI, 0xa6, 0x2f); - } else { - ast_set_index_reg(ast, AST_IO_VGACRI, 0xa7, 0x2f); - ast_set_index_reg(ast, AST_IO_VGACRI, 0xa6, 0x1f); - } + u8 vgacra6 = ast->quirks->crtc_mem_req_threshold_low; + u8 vgacra7 = ast->quirks->crtc_mem_req_threshold_high; + + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa7, vgacra7); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa6, vgacra6); } static void ast_set_sync_reg(struct ast_device *ast, |