Skip to content

Commit

Permalink
gpu: host1x: drm: Add memory manager and fb
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Arto Merilainen authored and Thierry Reding committed Apr 22, 2013
1 parent 692e6d7 commit de2ba66
Show file tree
Hide file tree
Showing 8 changed files with 700 additions and 34 deletions.
1 change: 1 addition & 0 deletions drivers/gpu/host1x/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG

host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
host1x-$(CONFIG_DRM_TEGRA) += drm/gem.o
obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
8 changes: 3 additions & 5 deletions drivers/gpu/host1x/drm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ config DRM_TEGRA
bool "NVIDIA Tegra DRM"
depends on DRM && OF
select DRM_KMS_HELPER
select DRM_GEM_CMA_HELPER
select DRM_KMS_CMA_HELPER
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select FB_SYS_FILLRECT
select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT
help
Choose this option if you have an NVIDIA Tegra SoC.

Expand Down
23 changes: 12 additions & 11 deletions drivers/gpu/host1x/drm/dc.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
#include <linux/platform_device.h>
#include <linux/clk/tegra.h>

#include "drm.h"
#include "dc.h"
#include "host1x_client.h"
#include "dc.h"
#include "drm.h"
#include "gem.h"

struct tegra_plane {
struct drm_plane base;
Expand Down Expand Up @@ -52,9 +53,9 @@ static int tegra_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
window.bits_per_pixel = fb->bits_per_pixel;

for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) {
struct drm_gem_cma_object *gem = drm_fb_cma_get_gem_obj(fb, i);
struct tegra_bo *bo = tegra_fb_get_plane(fb, i);

window.base[i] = gem->paddr + fb->offsets[i];
window.base[i] = bo->paddr + fb->offsets[i];

/*
* Tegra doesn't support different strides for U and V planes
Expand Down Expand Up @@ -137,15 +138,15 @@ static int tegra_dc_add_planes(struct drm_device *drm, struct tegra_dc *dc)
static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
struct drm_framebuffer *fb)
{
struct drm_gem_cma_object *gem = drm_fb_cma_get_gem_obj(fb, 0);
struct tegra_bo *bo = tegra_fb_get_plane(fb, 0);
unsigned long value;

tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER);

value = fb->offsets[0] + y * fb->pitches[0] +
x * fb->bits_per_pixel / 8;

tegra_dc_writel(dc, gem->paddr + value, DC_WINBUF_START_ADDR);
tegra_dc_writel(dc, bo->paddr + value, DC_WINBUF_START_ADDR);
tegra_dc_writel(dc, fb->pitches[0], DC_WIN_LINE_STRIDE);

value = GENERAL_UPDATE | WIN_A_UPDATE;
Expand Down Expand Up @@ -187,20 +188,20 @@ static void tegra_dc_finish_page_flip(struct tegra_dc *dc)
{
struct drm_device *drm = dc->base.dev;
struct drm_crtc *crtc = &dc->base;
struct drm_gem_cma_object *gem;
unsigned long flags, base;
struct tegra_bo *bo;

if (!dc->event)
return;

gem = drm_fb_cma_get_gem_obj(crtc->fb, 0);
bo = tegra_fb_get_plane(crtc->fb, 0);

/* check if new start address has been latched */
tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS);
base = tegra_dc_readl(dc, DC_WINBUF_START_ADDR);
tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS);

if (base == gem->paddr + crtc->fb->offsets[0]) {
if (base == bo->paddr + crtc->fb->offsets[0]) {
spin_lock_irqsave(&drm->event_lock, flags);
drm_send_vblank_event(drm, dc->pipe, dc->event);
drm_vblank_put(drm, dc->pipe);
Expand Down Expand Up @@ -570,7 +571,7 @@ static int tegra_crtc_mode_set(struct drm_crtc *crtc,
struct drm_display_mode *adjusted,
int x, int y, struct drm_framebuffer *old_fb)
{
struct drm_gem_cma_object *gem = drm_fb_cma_get_gem_obj(crtc->fb, 0);
struct tegra_bo *bo = tegra_fb_get_plane(crtc->fb, 0);
struct tegra_dc *dc = to_tegra_dc(crtc);
struct tegra_dc_window window;
unsigned long div, value;
Expand Down Expand Up @@ -617,7 +618,7 @@ static int tegra_crtc_mode_set(struct drm_crtc *crtc,
window.format = tegra_dc_format(crtc->fb->pixel_format);
window.bits_per_pixel = crtc->fb->bits_per_pixel;
window.stride[0] = crtc->fb->pitches[0];
window.base[0] = gem->paddr;
window.base[0] = bo->paddr;

err = tegra_dc_setup_window(dc, 0, &window);
if (err < 0)
Expand Down
17 changes: 10 additions & 7 deletions drivers/gpu/host1x/drm/drm.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
#include <asm/dma-iommu.h>

#include "host1x_client.h"
#include "dev.h"
#include "drm.h"
#include "gem.h"
#include "syncpt.h"

#define DRIVER_NAME "tegra"
#define DRIVER_DESC "NVIDIA Tegra graphics"
Expand Down Expand Up @@ -281,7 +284,7 @@ static void tegra_drm_lastclose(struct drm_device *drm)
{
struct host1x_drm *host1x = drm->dev_private;

drm_fbdev_cma_restore_mode(host1x->fbdev);
tegra_fbdev_restore_mode(host1x->fbdev);
}

static struct drm_ioctl_desc tegra_drm_ioctls[] = {
Expand All @@ -292,7 +295,7 @@ static const struct file_operations tegra_drm_fops = {
.open = drm_open,
.release = drm_release,
.unlocked_ioctl = drm_ioctl,
.mmap = drm_gem_cma_mmap,
.mmap = tegra_drm_mmap,
.poll = drm_poll,
.fasync = drm_fasync,
.read = drm_read,
Expand Down Expand Up @@ -408,11 +411,11 @@ struct drm_driver tegra_drm_driver = {
.debugfs_cleanup = tegra_debugfs_cleanup,
#endif

.gem_free_object = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,
.dumb_map_offset = drm_gem_cma_dumb_map_offset,
.dumb_destroy = drm_gem_cma_dumb_destroy,
.gem_free_object = tegra_bo_free_object,
.gem_vm_ops = &tegra_bo_vm_ops,
.dumb_create = tegra_bo_dumb_create,
.dumb_map_offset = tegra_bo_dumb_map_offset,
.dumb_destroy = tegra_bo_dumb_destroy,

.ioctls = tegra_drm_ioctls,
.num_ioctls = ARRAY_SIZE(tegra_drm_ioctls),
Expand Down
18 changes: 15 additions & 3 deletions drivers/gpu/host1x/drm/drm.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,19 @@
#include <drm/drm_crtc_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_gem_cma_helper.h>
#include <drm/drm_fb_cma_helper.h>
#include <drm/drm_fixed.h>

struct tegra_fb {
struct drm_framebuffer base;
struct tegra_bo **planes;
unsigned int num_planes;
};

struct tegra_fbdev {
struct drm_fb_helper base;
struct tegra_fb *fb;
};

struct host1x_drm {
struct drm_device *drm;
struct device *dev;
Expand All @@ -33,7 +42,7 @@ struct host1x_drm {
struct mutex clients_lock;
struct list_head clients;

struct drm_fbdev_cma *fbdev;
struct tegra_fbdev *fbdev;
};

struct host1x_client;
Expand Down Expand Up @@ -226,8 +235,11 @@ extern int tegra_output_init(struct drm_device *drm, struct tegra_output *output
extern int tegra_output_exit(struct tegra_output *output);

/* from fb.c */
struct tegra_bo *tegra_fb_get_plane(struct drm_framebuffer *framebuffer,
unsigned int index);
extern int tegra_drm_fb_init(struct drm_device *drm);
extern void tegra_drm_fb_exit(struct drm_device *drm);
extern void tegra_fbdev_restore_mode(struct tegra_fbdev *fbdev);

extern struct drm_driver tegra_drm_driver;

Expand Down
Loading

0 comments on commit de2ba66

Please sign in to comment.