Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 281350
b: refs/heads/master
c: a6a9182
h: refs/heads/master
v: v3
  • Loading branch information
Rob Clark authored and Greg Kroah-Hartman committed Dec 13, 2011
1 parent 8746b0a commit 7d9132b
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 47 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 65b0bd067df97737b9a13d92934d8f581cb0b07a
refs/heads/master: a6a918274116d8edc25eb20f6097dedf97b108e2
4 changes: 2 additions & 2 deletions trunk/drivers/staging/omapdrm/omap_dmm_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,12 @@
#define DMM_PATSTATUS_ERR_UPD_DATA (1<<14)
#define DMM_PATSTATUS_ERR_ACCESS (1<<15)

/* note: don't treat DMM_PATSTATUS_ERR_ACCESS as an error */
#define DMM_PATSTATUS_ERR (DMM_PATSTATUS_ERR_INV_DESCR | \
DMM_PATSTATUS_ERR_INV_DATA | \
DMM_PATSTATUS_ERR_UPD_AREA | \
DMM_PATSTATUS_ERR_UPD_CTRL | \
DMM_PATSTATUS_ERR_UPD_DATA | \
DMM_PATSTATUS_ERR_ACCESS)
DMM_PATSTATUS_ERR_UPD_DATA)



Expand Down
35 changes: 22 additions & 13 deletions trunk/drivers/staging/omapdrm/omap_dmm_tiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, struct tcm *tcm)
* corresponding slot is cleared (ie. dummy_pa is programmed)
*/
static int dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
struct page **pages)
struct page **pages, uint32_t npages, uint32_t roll)
{
dma_addr_t pat_pa = 0;
uint32_t *data;
Expand All @@ -197,8 +197,11 @@ static int dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
data = alloc_dma(txn, 4*i, &pat->data_pa);

while (i--) {
data[i] = (pages && pages[i]) ?
page_to_phys(pages[i]) : engine->dmm->dummy_pa;
int n = i + roll;
if (n >= npages)
n -= npages;
data[i] = (pages && pages[n]) ?
page_to_phys(pages[n]) : engine->dmm->dummy_pa;
}

/* fill in lut with new addresses */
Expand Down Expand Up @@ -262,7 +265,8 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
/*
* DMM programming
*/
static int fill(struct tcm_area *area, struct page **pages, bool wait)
static int fill(struct tcm_area *area, struct page **pages,
uint32_t npages, uint32_t roll, bool wait)
{
int ret = 0;
struct tcm_area slice, area_s;
Expand All @@ -278,12 +282,11 @@ static int fill(struct tcm_area *area, struct page **pages, bool wait)
.x1 = slice.p1.x, .y1 = slice.p1.y,
};

ret = dmm_txn_append(txn, &p_area, pages);
ret = dmm_txn_append(txn, &p_area, pages, npages, roll);
if (ret)
goto fail;

if (pages)
pages += tcm_sizeof(slice);
roll += tcm_sizeof(slice);
}

ret = dmm_txn_commit(txn, wait);
Expand All @@ -298,11 +301,12 @@ static int fill(struct tcm_area *area, struct page **pages, bool wait)

/* note: slots for which pages[i] == NULL are filled w/ dummy page
*/
int tiler_pin(struct tiler_block *block, struct page **pages, bool wait)
int tiler_pin(struct tiler_block *block, struct page **pages,
uint32_t npages, uint32_t roll, bool wait)
{
int ret;

ret = fill(&block->area, pages, wait);
ret = fill(&block->area, pages, npages, roll, wait);

if (ret)
tiler_unpin(block);
Expand All @@ -312,7 +316,7 @@ int tiler_pin(struct tiler_block *block, struct page **pages, bool wait)

int tiler_unpin(struct tiler_block *block)
{
return fill(&block->area, NULL, false);
return fill(&block->area, NULL, 0, 0, false);
}

/*
Expand Down Expand Up @@ -558,8 +562,13 @@ int omap_dmm_init(struct drm_device *dev)
goto fail;
}

/* enable some interrupts! */
writel(0xfefefefe, omap_dmm->base + DMM_PAT_IRQENABLE_SET);
/* Enable all interrupts for each refill engine except
* ERR_LUT_MISS<n> (which is just advisory, and we don't care
* about because we want to be able to refill live scanout
* buffers for accelerated pan/scroll) and FILL_DSC<n> which
* we just generally don't care about.
*/
writel(0x7e7e7e7e, omap_dmm->base + DMM_PAT_IRQENABLE_SET);

lut_table_size = omap_dmm->lut_width * omap_dmm->lut_height *
omap_dmm->num_lut;
Expand Down Expand Up @@ -658,7 +667,7 @@ int omap_dmm_init(struct drm_device *dev)
/* initialize all LUTs to dummy page entries */
for (i = 0; i < omap_dmm->num_lut; i++) {
area.tcm = omap_dmm->tcm[i];
if (fill(&area, NULL, true))
if (fill(&area, NULL, 0, 0, true))
dev_err(omap_dmm->dev, "refill failed");
}

Expand Down
3 changes: 2 additions & 1 deletion trunk/drivers/staging/omapdrm/omap_dmm_tiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ int omap_dmm_init(struct drm_device *dev);
int omap_dmm_remove(void);

/* pin/unpin */
int tiler_pin(struct tiler_block *block, struct page **pages, bool wait);
int tiler_pin(struct tiler_block *block, struct page **pages,
uint32_t npages, uint32_t roll, bool wait);
int tiler_unpin(struct tiler_block *block);

/* reserve/release */
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/staging/omapdrm/omap_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ struct omap_drm_private {
struct drm_connector *connectors[8];

struct drm_fb_helper *fbdev;

bool has_dmm;
};

struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev);
Expand Down Expand Up @@ -107,6 +109,7 @@ int omap_gem_op_finish(struct drm_gem_object *obj, enum omap_gem_op op);
int omap_gem_op_sync(struct drm_gem_object *obj, enum omap_gem_op op);
int omap_gem_op_async(struct drm_gem_object *obj, enum omap_gem_op op,
void (*fxn)(void *arg), void *arg);
int omap_gem_roll(struct drm_gem_object *obj, uint32_t roll);
int omap_gem_get_paddr(struct drm_gem_object *obj,
dma_addr_t *paddr, bool remap);
int omap_gem_put_paddr(struct drm_gem_object *obj);
Expand Down
22 changes: 3 additions & 19 deletions trunk/drivers/staging/omapdrm/omap_fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,25 +218,9 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,

size = PAGE_ALIGN(mode_cmd->pitch * mode_cmd->height);

if (bo) {
DBG("using existing %d byte buffer (needed %d)", bo->size, size);
if (size > bo->size) {
dev_err(dev->dev, "provided buffer object is too small!\n");
goto fail;
}
} else {
/* for convenience of all the various callers who don't want
* to be bothered to allocate their own buffer..
*/
union omap_gem_size gsize = {
.bytes = size,
};
DBG("allocating %d bytes for fb %d", size, dev->primary->index);
bo = omap_gem_new(dev, gsize, OMAP_BO_SCANOUT | OMAP_BO_WC);
if (!bo) {
dev_err(dev->dev, "failed to allocate buffer object\n");
goto fail;
}
if (size > bo->size) {
dev_err(dev->dev, "provided buffer object is too small!\n");
goto fail;
}

omap_fb->bo = bo;
Expand Down
73 changes: 68 additions & 5 deletions trunk/drivers/staging/omapdrm/omap_fbdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@
struct omap_fbdev {
struct drm_fb_helper base;
struct drm_framebuffer *fb;
struct drm_gem_object *bo;
};

static void omap_fbdev_flush(struct fb_info *fbi, int x, int y, int w, int h);
static struct drm_fb_helper *get_fb(struct fb_info *fbi);

static ssize_t omap_fbdev_write(struct fb_info *fbi, const char __user *buf,
size_t count, loff_t *ppos)
Expand Down Expand Up @@ -68,6 +70,31 @@ static void omap_fbdev_imageblit(struct fb_info *fbi,
image->width, image->height);
}

static int omap_fbdev_pan_display(struct fb_var_screeninfo *var,
struct fb_info *fbi)
{
struct drm_fb_helper *helper = get_fb(fbi);
struct omap_fbdev *fbdev = to_omap_fbdev(helper);
struct omap_drm_private *priv;
int npages;

if (!helper)
goto fallback;

priv = helper->dev->dev_private;
if (!priv->has_dmm)
goto fallback;

/* DMM roll shifts in 4K pages: */
npages = fbi->fix.line_length >> PAGE_SHIFT;
omap_gem_roll(fbdev->bo, var->yoffset * npages);

return 0;

fallback:
return drm_fb_helper_pan_display(var, fbi);
}

static struct fb_ops omap_fb_ops = {
.owner = THIS_MODULE,

Expand All @@ -82,7 +109,7 @@ static struct fb_ops omap_fb_ops = {

.fb_check_var = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
.fb_pan_display = drm_fb_helper_pan_display,
.fb_pan_display = omap_fbdev_pan_display,
.fb_blank = drm_fb_helper_blank,
.fb_setcmap = drm_fb_helper_setcmap,

Expand All @@ -95,7 +122,9 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
{
struct omap_fbdev *fbdev = to_omap_fbdev(helper);
struct drm_device *dev = helper->dev;
struct omap_drm_private *priv = dev->dev_private;
struct drm_framebuffer *fb = NULL;
union omap_gem_size gsize;
struct fb_info *fbi = NULL;
struct drm_mode_fb_cmd mode_cmd = {0};
dma_addr_t paddr;
Expand All @@ -109,16 +138,37 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
sizes->surface_bpp = 32;
sizes->surface_depth = 32;

DBG("create fbdev: %dx%d@%d", sizes->surface_width,
sizes->surface_height, sizes->surface_bpp);
DBG("create fbdev: %dx%d@%d (%dx%d)", sizes->surface_width,
sizes->surface_height, sizes->surface_bpp,
sizes->fb_width, sizes->fb_height);

mode_cmd.width = sizes->surface_width;
mode_cmd.height = sizes->surface_height;

mode_cmd.bpp = sizes->surface_bpp;
mode_cmd.depth = sizes->surface_depth;

fb = omap_framebuffer_init(dev, &mode_cmd, NULL);
mode_cmd.pitch = align_pitch(
mode_cmd.width * ((mode_cmd.bpp + 7) / 8),
mode_cmd.width, mode_cmd.bpp);

if (priv->has_dmm) {
/* need to align pitch to page size if using DMM scrolling */
mode_cmd.pitch = ALIGN(mode_cmd.pitch, PAGE_SIZE);
}

/* allocate backing bo */
gsize = (union omap_gem_size){
.bytes = PAGE_ALIGN(mode_cmd.pitch * mode_cmd.height),
};
DBG("allocating %d bytes for fb %d", gsize.bytes, dev->primary->index);
fbdev->bo = omap_gem_new(dev, gsize, OMAP_BO_SCANOUT | OMAP_BO_WC);
if (!fbdev->bo) {
dev_err(dev->dev, "failed to allocate buffer object\n");
goto fail;
}

fb = omap_framebuffer_init(dev, &mode_cmd, fbdev->bo);
if (!fb) {
dev_err(dev->dev, "failed to allocate fb\n");
ret = -ENOMEM;
Expand Down Expand Up @@ -153,7 +203,7 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
}

drm_fb_helper_fill_fix(fbi, fb->pitch, fb->depth);
drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height);
drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height);

size = omap_framebuffer_get_buffer(fb, 0, 0,
&vaddr, &paddr, &screen_width);
Expand All @@ -165,6 +215,15 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
fbi->fix.smem_start = paddr;
fbi->fix.smem_len = size;

/* if we have DMM, then we can use it for scrolling by just
* shuffling pages around in DMM rather than doing sw blit.
*/
if (priv->has_dmm) {
DRM_INFO("Enabling DMM ywrap scrolling\n");
fbi->flags |= FBINFO_HWACCEL_YWRAP | FBINFO_READS_FAST;
fbi->fix.ywrapstep = 1;
}

DBG("par=%p, %dx%d", fbi->par, fbi->var.xres, fbi->var.yres);
DBG("allocated %dx%d fb", fbdev->fb->width, fbdev->fb->height);

Expand Down Expand Up @@ -300,5 +359,9 @@ void omap_fbdev_free(struct drm_device *dev)

kfree(fbdev);

/* this will free the backing object */
if (fbdev->fb)
fbdev->fb->funcs->destroy(fbdev->fb);

priv->fbdev = NULL;
}
Loading

0 comments on commit 7d9132b

Please sign in to comment.