Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 358359
b: refs/heads/master
c: 3c03c46
h: refs/heads/master
i:
  358357: 35a3309
  358355: cb49e90
  358351: d9fffb9
v: v3
  • Loading branch information
Thierry Reding committed Feb 22, 2013
1 parent be4b9f0 commit 26d3a18
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6e5ff998997ba7dc5ca10b6662e95a9d07f764c4
refs/heads/master: 3c03c46ac80ea7edc3b8f2ba85085de54aec15cd
66 changes: 66 additions & 0 deletions trunk/drivers/gpu/drm/tegra/dc.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,72 @@ void tegra_dc_disable_vblank(struct tegra_dc *dc)
spin_unlock_irqrestore(&dc->lock, flags);
}

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;

if (!dc->event)
return;

gem = drm_fb_cma_get_gem_obj(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]) {
spin_lock_irqsave(&drm->event_lock, flags);
drm_send_vblank_event(drm, dc->pipe, dc->event);
drm_vblank_put(drm, dc->pipe);
dc->event = NULL;
spin_unlock_irqrestore(&drm->event_lock, flags);
}
}

void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
{
struct tegra_dc *dc = to_tegra_dc(crtc);
struct drm_device *drm = crtc->dev;
unsigned long flags;

spin_lock_irqsave(&drm->event_lock, flags);

if (dc->event && dc->event->base.file_priv == file) {
dc->event->base.destroy(&dc->event->base);
drm_vblank_put(drm, dc->pipe);
dc->event = NULL;
}

spin_unlock_irqrestore(&drm->event_lock, flags);
}

static int tegra_dc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event)
{
struct tegra_dc *dc = to_tegra_dc(crtc);
struct drm_device *drm = crtc->dev;

if (dc->event)
return -EBUSY;

if (event) {
event->pipe = dc->pipe;
dc->event = event;
drm_vblank_get(drm, dc->pipe);
}

tegra_dc_set_base(dc, 0, 0, fb);
crtc->fb = fb;

return 0;
}

static const struct drm_crtc_funcs tegra_crtc_funcs = {
.page_flip = tegra_dc_page_flip,
.set_config = drm_crtc_helper_set_config,
.destroy = drm_crtc_cleanup,
};
Expand Down Expand Up @@ -665,6 +730,7 @@ static irqreturn_t tegra_dc_irq(int irq, void *data)
dev_dbg(dc->dev, "%s(): vertical blank\n", __func__);
*/
drm_handle_vblank(dc->base.dev, dc->pipe);
tegra_dc_finish_page_flip(dc);
}

if (status & (WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT)) {
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/gpu/drm/tegra/dc.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@
#define DC_CMD_SIGNAL_RAISE3 0x03e

#define DC_CMD_STATE_ACCESS 0x040
#define READ_MUX (1 << 0)
#define WRITE_MUX (1 << 2)

#define DC_CMD_STATE_CONTROL 0x041
#define GENERAL_ACT_REQ (1 << 0)
Expand Down
9 changes: 9 additions & 0 deletions trunk/drivers/gpu/drm/tegra/drm.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,20 @@ static void tegra_drm_disable_vblank(struct drm_device *drm, int pipe)
tegra_dc_disable_vblank(dc);
}

static void tegra_drm_preclose(struct drm_device *drm, struct drm_file *file)
{
struct drm_crtc *crtc;

list_for_each_entry(crtc, &drm->mode_config.crtc_list, head)
tegra_dc_cancel_page_flip(crtc, file);
}

struct drm_driver tegra_drm_driver = {
.driver_features = DRIVER_BUS_PLATFORM | DRIVER_MODESET | DRIVER_GEM,
.load = tegra_drm_load,
.unload = tegra_drm_unload,
.open = tegra_drm_open,
.preclose = tegra_drm_preclose,
.lastclose = tegra_drm_lastclose,

.get_vblank_counter = tegra_drm_get_vblank_counter,
Expand Down
5 changes: 5 additions & 0 deletions trunk/drivers/gpu/drm/tegra/drm.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ struct tegra_dc {
struct drm_info_list *debugfs_files;
struct drm_minor *minor;
struct dentry *debugfs;

/* page-flip handling */
struct drm_pending_vblank_event *event;
};

static inline struct tegra_dc *host1x_client_to_dc(struct host1x_client *client)
Expand Down Expand Up @@ -133,6 +136,8 @@ extern int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
const struct tegra_dc_window *window);
extern void tegra_dc_enable_vblank(struct tegra_dc *dc);
extern void tegra_dc_disable_vblank(struct tegra_dc *dc);
extern void tegra_dc_cancel_page_flip(struct drm_crtc *crtc,
struct drm_file *file);

struct tegra_output_ops {
int (*enable)(struct tegra_output *output);
Expand Down

0 comments on commit 26d3a18

Please sign in to comment.