summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/ast
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/ast')
-rw-r--r--drivers/gpu/drm/ast/ast_2000.c9
-rw-r--r--drivers/gpu/drm/ast/ast_2100.c9
-rw-r--r--drivers/gpu/drm/ast/ast_2200.c9
-rw-r--r--drivers/gpu/drm/ast/ast_2300.c9
-rw-r--r--drivers/gpu/drm/ast/ast_2400.c9
-rw-r--r--drivers/gpu/drm/ast/ast_2500.c10
-rw-r--r--drivers/gpu/drm/ast/ast_2600.c11
-rw-r--r--drivers/gpu/drm/ast/ast_drv.c4
-rw-r--r--drivers/gpu/drm/ast/ast_drv.h27
-rw-r--r--drivers/gpu/drm/ast/ast_mode.c46
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,