diff options
Diffstat (limited to 'drivers/gpu/drm/ast')
-rw-r--r-- | drivers/gpu/drm/ast/ast_cursor.c | 27 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_drv.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_drv.h | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_main.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_mode.c | 40 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_tables.h | 6 |
6 files changed, 61 insertions, 31 deletions
diff --git a/drivers/gpu/drm/ast/ast_cursor.c b/drivers/gpu/drm/ast/ast_cursor.c index e0f4613918ad..742d43a7edf4 100644 --- a/drivers/gpu/drm/ast/ast_cursor.c +++ b/drivers/gpu/drm/ast/ast_cursor.c @@ -39,7 +39,7 @@ static void ast_cursor_fini(struct ast_private *ast) for (i = 0; i < ARRAY_SIZE(ast->cursor.gbo); ++i) { gbo = ast->cursor.gbo[i]; - drm_gem_vram_vunmap(gbo, ast->cursor.vaddr[i]); + drm_gem_vram_vunmap(gbo, &ast->cursor.map[i]); drm_gem_vram_unpin(gbo); drm_gem_vram_put(gbo); } @@ -60,7 +60,7 @@ int ast_cursor_init(struct ast_private *ast) struct drm_device *dev = &ast->base; size_t size, i; struct drm_gem_vram_object *gbo; - void __iomem *vaddr; + struct dma_buf_map map; int ret; size = roundup(AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE, PAGE_SIZE); @@ -77,16 +77,15 @@ int ast_cursor_init(struct ast_private *ast) drm_gem_vram_put(gbo); goto err_drm_gem_vram_put; } - vaddr = drm_gem_vram_vmap(gbo); - if (IS_ERR(vaddr)) { - ret = PTR_ERR(vaddr); + ret = drm_gem_vram_vmap(gbo, &map); + if (ret) { drm_gem_vram_unpin(gbo); drm_gem_vram_put(gbo); goto err_drm_gem_vram_put; } ast->cursor.gbo[i] = gbo; - ast->cursor.vaddr[i] = vaddr; + ast->cursor.map[i] = map; } return drmm_add_action_or_reset(dev, ast_cursor_release, NULL); @@ -95,7 +94,7 @@ err_drm_gem_vram_put: while (i) { --i; gbo = ast->cursor.gbo[i]; - drm_gem_vram_vunmap(gbo, ast->cursor.vaddr[i]); + drm_gem_vram_vunmap(gbo, &ast->cursor.map[i]); drm_gem_vram_unpin(gbo); drm_gem_vram_put(gbo); } @@ -170,6 +169,7 @@ int ast_cursor_blit(struct ast_private *ast, struct drm_framebuffer *fb) { struct drm_device *dev = &ast->base; struct drm_gem_vram_object *gbo; + struct dma_buf_map map; int ret; void *src; void __iomem *dst; @@ -183,18 +183,17 @@ int ast_cursor_blit(struct ast_private *ast, struct drm_framebuffer *fb) ret = drm_gem_vram_pin(gbo, 0); if (ret) return ret; - src = drm_gem_vram_vmap(gbo); - if (IS_ERR(src)) { - ret = PTR_ERR(src); + ret = drm_gem_vram_vmap(gbo, &map); + if (ret) goto err_drm_gem_vram_unpin; - } + src = map.vaddr; /* TODO: Use mapping abstraction properly */ - dst = ast->cursor.vaddr[ast->cursor.next_index]; + dst = ast->cursor.map[ast->cursor.next_index].vaddr_iomem; /* do data transfer to cursor BO */ update_cursor_image(dst, src, fb->width, fb->height); - drm_gem_vram_vunmap(gbo, src); + drm_gem_vram_vunmap(gbo, &map); drm_gem_vram_unpin(gbo); return 0; @@ -257,7 +256,7 @@ void ast_cursor_show(struct ast_private *ast, int x, int y, u8 __iomem *sig; u8 jreg; - dst = ast->cursor.vaddr[ast->cursor.next_index]; + dst = ast->cursor.map[ast->cursor.next_index].vaddr; sig = dst + AST_HWC_SIZE; writel(x, sig + AST_HWC_SIGNATURE_X); diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index f0b4af1c390a..667b450606ef 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -49,7 +49,7 @@ module_param_named(modeset, ast_modeset, int, 0400); DEFINE_DRM_GEM_FOPS(ast_fops); -static struct drm_driver ast_driver = { +static const struct drm_driver ast_driver = { .driver_features = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET, diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 467049ca8430..ccaff81924ee 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -28,10 +28,11 @@ #ifndef __AST_DRV_H__ #define __AST_DRV_H__ -#include <linux/types.h> -#include <linux/io.h> +#include <linux/dma-buf-map.h> #include <linux/i2c.h> #include <linux/i2c-algo-bit.h> +#include <linux/io.h> +#include <linux/types.h> #include <drm/drm_connector.h> #include <drm/drm_crtc.h> @@ -63,6 +64,7 @@ enum ast_chip { AST2300, AST2400, AST2500, + AST2600, }; enum ast_tx_chip { @@ -131,7 +133,7 @@ struct ast_private { struct { struct drm_gem_vram_object *gbo[AST_DEFAULT_HWC_NUM]; - void __iomem *vaddr[AST_DEFAULT_HWC_NUM]; + struct dma_buf_map map[AST_DEFAULT_HWC_NUM]; unsigned int next_index; } cursor; @@ -159,7 +161,7 @@ static inline struct ast_private *to_ast_private(struct drm_device *dev) return container_of(dev, struct ast_private, base); } -struct ast_private *ast_device_create(struct drm_driver *drv, +struct ast_private *ast_device_create(const struct drm_driver *drv, struct pci_dev *pdev, unsigned long flags); diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index 77066bca8793..1b13199858cb 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -143,7 +143,10 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post) ast_detect_config_mode(dev, &scu_rev); /* Identify chipset */ - if (dev->pdev->revision >= 0x40) { + if (dev->pdev->revision >= 0x50) { + ast->chip = AST2600; + drm_info(dev, "AST 2600 detected\n"); + } else if (dev->pdev->revision >= 0x40) { ast->chip = AST2500; drm_info(dev, "AST 2500 detected\n"); } else if (dev->pdev->revision >= 0x30) { @@ -392,7 +395,7 @@ static void ast_device_release(void *data) ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x04); } -struct ast_private *ast_device_create(struct drm_driver *drv, +struct ast_private *ast_device_create(const struct drm_driver *drv, struct pci_dev *pdev, unsigned long flags) { diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 834a156e3a75..9db371f4054f 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -742,7 +742,6 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) case DRM_MODE_DPMS_SUSPEND: if (ast->tx_chip_type == AST_TX_DP501) ast_set_dp501_video_output(crtc->dev, 1); - ast_crtc_load_lut(ast, crtc); break; case DRM_MODE_DPMS_OFF: if (ast->tx_chip_type == AST_TX_DP501) @@ -752,24 +751,26 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) } static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc, - struct drm_crtc_state *state) + struct drm_atomic_state *state) { + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, + crtc); struct drm_device *dev = crtc->dev; struct ast_crtc_state *ast_state; const struct drm_format_info *format; bool succ; - if (!state->enable) + if (!crtc_state->enable) return 0; /* no mode checks if CRTC is being disabled */ - ast_state = to_ast_crtc_state(state); + ast_state = to_ast_crtc_state(crtc_state); format = ast_state->format; if (drm_WARN_ON_ONCE(dev, !format)) return -EINVAL; /* BUG: We didn't set format in primary check(). */ - succ = ast_get_vbios_mode_info(format, &state->mode, - &state->adjusted_mode, + succ = ast_get_vbios_mode_info(format, &crtc_state->mode, + &crtc_state->adjusted_mode, &ast_state->vbios_mode_info); if (!succ) return -EINVAL; @@ -778,8 +779,28 @@ static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc, } static void +ast_crtc_helper_atomic_flush(struct drm_crtc *crtc, + struct drm_atomic_state *state) +{ + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, + crtc); + struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, + crtc); + struct ast_private *ast = to_ast_private(crtc->dev); + struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state); + struct ast_crtc_state *old_ast_crtc_state = to_ast_crtc_state(old_crtc_state); + + /* + * The gamma LUT has to be reloaded after changing the primary + * plane's color format. + */ + if (old_ast_crtc_state->format != ast_crtc_state->format) + ast_crtc_load_lut(ast, crtc); +} + +static void ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { struct drm_device *dev = crtc->dev; struct ast_private *ast = to_ast_private(dev); @@ -802,8 +823,10 @@ ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, static void ast_crtc_helper_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { + struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, + crtc); struct drm_device *dev = crtc->dev; struct ast_private *ast = to_ast_private(dev); @@ -830,6 +853,7 @@ ast_crtc_helper_atomic_disable(struct drm_crtc *crtc, static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = { .atomic_check = ast_crtc_helper_atomic_check, + .atomic_flush = ast_crtc_helper_atomic_flush, .atomic_enable = ast_crtc_helper_atomic_enable, .atomic_disable = ast_crtc_helper_atomic_disable, }; diff --git a/drivers/gpu/drm/ast/ast_tables.h b/drivers/gpu/drm/ast/ast_tables.h index d665dd5af5dd..d9eb353a4bf0 100644 --- a/drivers/gpu/drm/ast/ast_tables.h +++ b/drivers/gpu/drm/ast/ast_tables.h @@ -282,6 +282,8 @@ static const struct ast_vbios_enhtable res_1360x768[] = { }; static const struct ast_vbios_enhtable res_1600x900[] = { + {1800, 1600, 24, 80, 1000, 900, 1, 3, VCLK108, /* 60Hz */ + (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 3, 0x3A }, {1760, 1600, 48, 32, 926, 900, 3, 5, VCLK97_75, /* 60Hz CVT RB */ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | AST2500PreCatchCRT), 60, 1, 0x3A }, @@ -293,10 +295,10 @@ static const struct ast_vbios_enhtable res_1600x900[] = { static const struct ast_vbios_enhtable res_1920x1080[] = { {2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5, /* 60Hz */ - (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | + (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | AST2500PreCatchCRT), 60, 1, 0x38 }, {2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5, /* 60Hz */ - (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | + (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | AST2500PreCatchCRT), 0xFF, 1, 0x38 }, }; |