diff options
| author | Arto Merilainen <amerilainen@nvidia.com> | 2013-03-22 10:34:08 -0400 |
|---|---|---|
| committer | Thierry Reding <thierry.reding@avionic-design.de> | 2013-04-22 06:40:04 -0400 |
| commit | de2ba664c30fcdb0f678ab6cbb57e01a0b206085 (patch) | |
| tree | ff5cca80336ae30f9d050305750a89332d4198a8 /drivers/gpu/host1x/drm | |
| parent | 692e6d7be8099225f04b2d97299bc03479a5fcdb (diff) | |
gpu: host1x: drm: Add memory manager and fb
This patch introduces a memory manager for tegra drm and moves
existing parts to use it. As cma framebuffer helpers can no more
be used, this patch adds also a separate framebuffer driver for
tegra.
Signed-off-by: Arto Merilainen <amerilainen@nvidia.com>
Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-by: Thierry Reding <thierry.reding@avionic-design.de>
Tested-by: Thierry Reding <thierry.reding@avionic-design.de>
Tested-by: Erik Faye-Lund <kusmabite@gmail.com>
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
Diffstat (limited to 'drivers/gpu/host1x/drm')
| -rw-r--r-- | drivers/gpu/host1x/drm/Kconfig | 8 | ||||
| -rw-r--r-- | drivers/gpu/host1x/drm/dc.c | 23 | ||||
| -rw-r--r-- | drivers/gpu/host1x/drm/drm.c | 17 | ||||
| -rw-r--r-- | drivers/gpu/host1x/drm/drm.h | 18 | ||||
| -rw-r--r-- | drivers/gpu/host1x/drm/fb.c | 338 | ||||
| -rw-r--r-- | drivers/gpu/host1x/drm/gem.c | 270 | ||||
| -rw-r--r-- | drivers/gpu/host1x/drm/gem.h | 59 |
7 files changed, 699 insertions, 34 deletions
diff --git a/drivers/gpu/host1x/drm/Kconfig b/drivers/gpu/host1x/drm/Kconfig index 33f8f7a39196..9a28901d07ce 100644 --- a/drivers/gpu/host1x/drm/Kconfig +++ b/drivers/gpu/host1x/drm/Kconfig | |||
| @@ -2,11 +2,9 @@ config DRM_TEGRA | |||
| 2 | bool "NVIDIA Tegra DRM" | 2 | bool "NVIDIA Tegra DRM" |
| 3 | depends on DRM && OF | 3 | depends on DRM && OF |
| 4 | select DRM_KMS_HELPER | 4 | select DRM_KMS_HELPER |
| 5 | select DRM_GEM_CMA_HELPER | 5 | select FB_SYS_FILLRECT |
| 6 | select DRM_KMS_CMA_HELPER | 6 | select FB_SYS_COPYAREA |
| 7 | select FB_CFB_FILLRECT | 7 | select FB_SYS_IMAGEBLIT |
| 8 | select FB_CFB_COPYAREA | ||
| 9 | select FB_CFB_IMAGEBLIT | ||
| 10 | help | 8 | help |
| 11 | Choose this option if you have an NVIDIA Tegra SoC. | 9 | Choose this option if you have an NVIDIA Tegra SoC. |
| 12 | 10 | ||
diff --git a/drivers/gpu/host1x/drm/dc.c b/drivers/gpu/host1x/drm/dc.c index 29a79b66f36c..85ea6163a7b0 100644 --- a/drivers/gpu/host1x/drm/dc.c +++ b/drivers/gpu/host1x/drm/dc.c | |||
| @@ -14,9 +14,10 @@ | |||
| 14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
| 15 | #include <linux/clk/tegra.h> | 15 | #include <linux/clk/tegra.h> |
| 16 | 16 | ||
| 17 | #include "drm.h" | ||
| 18 | #include "dc.h" | ||
| 19 | #include "host1x_client.h" | 17 | #include "host1x_client.h" |
| 18 | #include "dc.h" | ||
| 19 | #include "drm.h" | ||
| 20 | #include "gem.h" | ||
| 20 | 21 | ||
| 21 | struct tegra_plane { | 22 | struct tegra_plane { |
| 22 | struct drm_plane base; | 23 | struct drm_plane base; |
| @@ -52,9 +53,9 @@ static int tegra_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, | |||
| 52 | window.bits_per_pixel = fb->bits_per_pixel; | 53 | window.bits_per_pixel = fb->bits_per_pixel; |
| 53 | 54 | ||
| 54 | for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) { | 55 | for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) { |
| 55 | struct drm_gem_cma_object *gem = drm_fb_cma_get_gem_obj(fb, i); | 56 | struct tegra_bo *bo = tegra_fb_get_plane(fb, i); |
| 56 | 57 | ||
| 57 | window.base[i] = gem->paddr + fb->offsets[i]; | 58 | window.base[i] = bo->paddr + fb->offsets[i]; |
| 58 | 59 | ||
| 59 | /* | 60 | /* |
| 60 | * Tegra doesn't support different strides for U and V planes | 61 | * Tegra doesn't support different strides for U and V planes |
| @@ -137,7 +138,7 @@ static int tegra_dc_add_planes(struct drm_device *drm, struct tegra_dc *dc) | |||
| 137 | static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y, | 138 | static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y, |
| 138 | struct drm_framebuffer *fb) | 139 | struct drm_framebuffer *fb) |
| 139 | { | 140 | { |
| 140 | struct drm_gem_cma_object *gem = drm_fb_cma_get_gem_obj(fb, 0); | 141 | struct tegra_bo *bo = tegra_fb_get_plane(fb, 0); |
| 141 | unsigned long value; | 142 | unsigned long value; |
| 142 | 143 | ||
| 143 | tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER); | 144 | tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER); |
| @@ -145,7 +146,7 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y, | |||
| 145 | value = fb->offsets[0] + y * fb->pitches[0] + | 146 | value = fb->offsets[0] + y * fb->pitches[0] + |
| 146 | x * fb->bits_per_pixel / 8; | 147 | x * fb->bits_per_pixel / 8; |
| 147 | 148 | ||
| 148 | tegra_dc_writel(dc, gem->paddr + value, DC_WINBUF_START_ADDR); | 149 | tegra_dc_writel(dc, bo->paddr + value, DC_WINBUF_START_ADDR); |
| 149 | tegra_dc_writel(dc, fb->pitches[0], DC_WIN_LINE_STRIDE); | 150 | tegra_dc_writel(dc, fb->pitches[0], DC_WIN_LINE_STRIDE); |
| 150 | 151 | ||
| 151 | value = GENERAL_UPDATE | WIN_A_UPDATE; | 152 | value = GENERAL_UPDATE | WIN_A_UPDATE; |
| @@ -187,20 +188,20 @@ static void tegra_dc_finish_page_flip(struct tegra_dc *dc) | |||
| 187 | { | 188 | { |
| 188 | struct drm_device *drm = dc->base.dev; | 189 | struct drm_device *drm = dc->base.dev; |
| 189 | struct drm_crtc *crtc = &dc->base; | 190 | struct drm_crtc *crtc = &dc->base; |
| 190 | struct drm_gem_cma_object *gem; | ||
| 191 | unsigned long flags, base; | 191 | unsigned long flags, base; |
| 192 | struct tegra_bo *bo; | ||
| 192 | 193 | ||
| 193 | if (!dc->event) | 194 | if (!dc->event) |
| 194 | return; | 195 | return; |
| 195 | 196 | ||
| 196 | gem = drm_fb_cma_get_gem_obj(crtc->fb, 0); | 197 | bo = tegra_fb_get_plane(crtc->fb, 0); |
| 197 | 198 | ||
| 198 | /* check if new start address has been latched */ | 199 | /* check if new start address has been latched */ |
| 199 | tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS); | 200 | tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS); |
| 200 | base = tegra_dc_readl(dc, DC_WINBUF_START_ADDR); | 201 | base = tegra_dc_readl(dc, DC_WINBUF_START_ADDR); |
| 201 | tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS); | 202 | tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS); |
| 202 | 203 | ||
| 203 | if (base == gem->paddr + crtc->fb->offsets[0]) { | 204 | if (base == bo->paddr + crtc->fb->offsets[0]) { |
| 204 | spin_lock_irqsave(&drm->event_lock, flags); | 205 | spin_lock_irqsave(&drm->event_lock, flags); |
| 205 | drm_send_vblank_event(drm, dc->pipe, dc->event); | 206 | drm_send_vblank_event(drm, dc->pipe, dc->event); |
| 206 | drm_vblank_put(drm, dc->pipe); | 207 | drm_vblank_put(drm, dc->pipe); |
| @@ -570,7 +571,7 @@ static int tegra_crtc_mode_set(struct drm_crtc *crtc, | |||
| 570 | struct drm_display_mode *adjusted, | 571 | struct drm_display_mode *adjusted, |
| 571 | int x, int y, struct drm_framebuffer *old_fb) | 572 | int x, int y, struct drm_framebuffer *old_fb) |
| 572 | { | 573 | { |
| 573 | struct drm_gem_cma_object *gem = drm_fb_cma_get_gem_obj(crtc->fb, 0); | 574 | struct tegra_bo *bo = tegra_fb_get_plane(crtc->fb, 0); |
| 574 | struct tegra_dc *dc = to_tegra_dc(crtc); | 575 | struct tegra_dc *dc = to_tegra_dc(crtc); |
| 575 | struct tegra_dc_window window; | 576 | struct tegra_dc_window window; |
| 576 | unsigned long div, value; | 577 | unsigned long div, value; |
| @@ -617,7 +618,7 @@ static int tegra_crtc_mode_set(struct drm_crtc *crtc, | |||
| 617 | window.format = tegra_dc_format(crtc->fb->pixel_format); | 618 | window.format = tegra_dc_format(crtc->fb->pixel_format); |
| 618 | window.bits_per_pixel = crtc->fb->bits_per_pixel; | 619 | window.bits_per_pixel = crtc->fb->bits_per_pixel; |
| 619 | window.stride[0] = crtc->fb->pitches[0]; | 620 | window.stride[0] = crtc->fb->pitches[0]; |
| 620 | window.base[0] = gem->paddr; | 621 | window.base[0] = bo->paddr; |
| 621 | 622 | ||
| 622 | err = tegra_dc_setup_window(dc, 0, &window); | 623 | err = tegra_dc_setup_window(dc, 0, &window); |
| 623 | if (err < 0) | 624 | if (err < 0) |
diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c index 901f0b47815c..c4e45c16f991 100644 --- a/drivers/gpu/host1x/drm/drm.c +++ b/drivers/gpu/host1x/drm/drm.c | |||
| @@ -15,7 +15,10 @@ | |||
| 15 | #include <asm/dma-iommu.h> | 15 | #include <asm/dma-iommu.h> |
| 16 | 16 | ||
| 17 | #include "host1x_client.h" | 17 | #include "host1x_client.h" |
| 18 | #include "dev.h" | ||
| 18 | #include "drm.h" | 19 | #include "drm.h" |
| 20 | #include "gem.h" | ||
| 21 | #include "syncpt.h" | ||
| 19 | 22 | ||
| 20 | #define DRIVER_NAME "tegra" | 23 | #define DRIVER_NAME "tegra" |
| 21 | #define DRIVER_DESC "NVIDIA Tegra graphics" | 24 | #define DRIVER_DESC "NVIDIA Tegra graphics" |
| @@ -281,7 +284,7 @@ static void tegra_drm_lastclose(struct drm_device *drm) | |||
| 281 | { | 284 | { |
| 282 | struct host1x_drm *host1x = drm->dev_private; | 285 | struct host1x_drm *host1x = drm->dev_private; |
| 283 | 286 | ||
| 284 | drm_fbdev_cma_restore_mode(host1x->fbdev); | 287 | tegra_fbdev_restore_mode(host1x->fbdev); |
| 285 | } | 288 | } |
| 286 | 289 | ||
| 287 | static struct drm_ioctl_desc tegra_drm_ioctls[] = { | 290 | static struct drm_ioctl_desc tegra_drm_ioctls[] = { |
| @@ -292,7 +295,7 @@ static const struct file_operations tegra_drm_fops = { | |||
| 292 | .open = drm_open, | 295 | .open = drm_open, |
| 293 | .release = drm_release, | 296 | .release = drm_release, |
| 294 | .unlocked_ioctl = drm_ioctl, | 297 | .unlocked_ioctl = drm_ioctl, |
| 295 | .mmap = drm_gem_cma_mmap, | 298 | .mmap = tegra_drm_mmap, |
| 296 | .poll = drm_poll, | 299 | .poll = drm_poll, |
| 297 | .fasync = drm_fasync, | 300 | .fasync = drm_fasync, |
| 298 | .read = drm_read, | 301 | .read = drm_read, |
| @@ -408,11 +411,11 @@ struct drm_driver tegra_drm_driver = { | |||
| 408 | .debugfs_cleanup = tegra_debugfs_cleanup, | 411 | .debugfs_cleanup = tegra_debugfs_cleanup, |
| 409 | #endif | 412 | #endif |
| 410 | 413 | ||
