Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 324527
b: refs/heads/master
c: 3c810c6
h: refs/heads/master
i:
  324525: 3cb85e4
  324523: dc9e10b
  324519: 0ab0db9
  324511: aa57f68
v: v3
  • Loading branch information
Rob Clark authored and Greg Kroah-Hartman committed Aug 15, 2012
1 parent d0d8f96 commit 13a4af2
Show file tree
Hide file tree
Showing 9 changed files with 312 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: 69af59970bec925d182ca5ebd80e643fdd90b1cc
refs/heads/master: 3c810c613a9d61eb70735cfb85fe5db6e0331bae
10 changes: 10 additions & 0 deletions trunk/drivers/staging/omapdrm/omap_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,18 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc,
return 0;
}

static int omap_crtc_set_property(struct drm_crtc *crtc,
struct drm_property *property, uint64_t val)
{
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
return omap_plane_set_property(omap_crtc->plane, property, val);
}

static const struct drm_crtc_funcs omap_crtc_funcs = {
.set_config = drm_crtc_helper_set_config,
.destroy = omap_crtc_destroy,
.page_flip = omap_crtc_page_flip_locked,
.set_property = omap_crtc_set_property,
};

static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs = {
Expand Down Expand Up @@ -231,6 +239,8 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
drm_crtc_init(dev, crtc, &omap_crtc_funcs);
drm_crtc_helper_add(crtc, &omap_crtc_helper_funcs);

omap_plane_install_properties(omap_crtc->plane, &crtc->base);

return crtc;

fail:
Expand Down
47 changes: 41 additions & 6 deletions trunk/drivers/staging/omapdrm/omap_dmm_tiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,8 +404,26 @@ int tiler_release(struct tiler_block *block)
* Utils
*/

/* calculate the tiler space address of a pixel in a view orientation */
static u32 tiler_get_address(u32 orient, enum tiler_fmt fmt, u32 x, u32 y)
/* calculate the tiler space address of a pixel in a view orientation...
* below description copied from the display subsystem section of TRM:
*
* When the TILER is addressed, the bits:
* [28:27] = 0x0 for 8-bit tiled
* 0x1 for 16-bit tiled
* 0x2 for 32-bit tiled
* 0x3 for page mode
* [31:29] = 0x0 for 0-degree view
* 0x1 for 180-degree view + mirroring
* 0x2 for 0-degree view + mirroring
* 0x3 for 180-degree view
* 0x4 for 270-degree view + mirroring
* 0x5 for 270-degree view
* 0x6 for 90-degree view
* 0x7 for 90-degree view + mirroring
* Otherwise the bits indicated the corresponding bit address to access
* the SDRAM.
*/
static u32 tiler_get_address(enum tiler_fmt fmt, u32 orient, u32 x, u32 y)
{
u32 x_bits, y_bits, tmp, x_mask, y_mask, alignment;

Expand All @@ -417,8 +435,11 @@ static u32 tiler_get_address(u32 orient, enum tiler_fmt fmt, u32 x, u32 y)
x_mask = MASK(x_bits);
y_mask = MASK(y_bits);

if (x < 0 || x > x_mask || y < 0 || y > y_mask)
if (x < 0 || x > x_mask || y < 0 || y > y_mask) {
DBG("invalid coords: %u < 0 || %u > %u || %u < 0 || %u > %u",
x, x, x_mask, y, y, y_mask);
return 0;
}

/* account for mirroring */
if (orient & MASK_X_INVERT)
Expand All @@ -439,23 +460,37 @@ dma_addr_t tiler_ssptr(struct tiler_block *block)
{
BUG_ON(!validfmt(block->fmt));

return TILVIEW_8BIT + tiler_get_address(0, block->fmt,
return TILVIEW_8BIT + tiler_get_address(block->fmt, 0,
block->area.p0.x * geom[block->fmt].slot_w,
block->area.p0.y * geom[block->fmt].slot_h);
}

dma_addr_t tiler_tsptr(struct tiler_block *block, uint32_t orient,
uint32_t x, uint32_t y)
{
struct tcm_pt *p = &block->area.p0;
BUG_ON(!validfmt(block->fmt));

return tiler_get_address(block->fmt, orient,
(p->x * geom[block->fmt].slot_w) + x,
(p->y * geom[block->fmt].slot_h) + y);
}

void tiler_align(enum tiler_fmt fmt, uint16_t *w, uint16_t *h)
{
BUG_ON(!validfmt(fmt));
*w = round_up(*w, geom[fmt].slot_w);
*h = round_up(*h, geom[fmt].slot_h);
}

uint32_t tiler_stride(enum tiler_fmt fmt)
uint32_t tiler_stride(enum tiler_fmt fmt, uint32_t orient)
{
BUG_ON(!validfmt(fmt));

return 1 << (CONT_WIDTH_BITS + geom[fmt].y_shft);
if (orient & MASK_XY_FLIP)
return 1 << (CONT_HEIGHT_BITS + geom[fmt].x_shft);
else
return 1 << (CONT_WIDTH_BITS + geom[fmt].y_shft);
}

size_t tiler_size(enum tiler_fmt fmt, uint16_t w, uint16_t h)
Expand Down
17 changes: 15 additions & 2 deletions trunk/drivers/staging/omapdrm/omap_dmm_tiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,18 @@ struct tiler_block {
#define TILER_WIDTH (1 << (CONT_WIDTH_BITS - SLOT_WIDTH_BITS))
#define TILER_HEIGHT (1 << (CONT_HEIGHT_BITS - SLOT_HEIGHT_BITS))

/* tiler space addressing bitfields */
/*
Table 15-11. Coding and Description of TILER Orientations
S Y X Description Alternate description
0 0 0 0-degree view Natural view
0 0 1 0-degree view with vertical mirror 180-degree view with horizontal mirror
0 1 0 0-degree view with horizontal mirror 180-degree view with vertical mirror
0 1 1 180-degree view
1 0 0 90-degree view with vertical mirror 270-degree view with horizontal mirror
1 0 1 270-degree view
1 1 0 90-degree view
1 1 1 90-degree view with horizontal mirror 270-degree view with vertical mirror
*/
#define MASK_XY_FLIP (1 << 31)
#define MASK_Y_INVERT (1 << 30)
#define MASK_X_INVERT (1 << 29)
Expand Down Expand Up @@ -90,7 +101,9 @@ int tiler_release(struct tiler_block *block);

/* utilities */
dma_addr_t tiler_ssptr(struct tiler_block *block);
uint32_t tiler_stride(enum tiler_fmt fmt);
dma_addr_t tiler_tsptr(struct tiler_block *block, uint32_t orient,
uint32_t x, uint32_t y);
uint32_t tiler_stride(enum tiler_fmt fmt, uint32_t orient);
size_t tiler_size(enum tiler_fmt fmt, uint16_t w, uint16_t h);
size_t tiler_vsize(enum tiler_fmt fmt, uint16_t w, uint16_t h);
void tiler_align(enum tiler_fmt fmt, uint16_t *w, uint16_t *h);
Expand Down
17 changes: 17 additions & 0 deletions trunk/drivers/staging/omapdrm/omap_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,8 @@ static int dev_firstopen(struct drm_device *dev)
*/
static void dev_lastclose(struct drm_device *dev)
{
int i;

/* we don't support vga-switcheroo.. so just make sure the fbdev
* mode is active
*/
Expand All @@ -657,6 +659,21 @@ static void dev_lastclose(struct drm_device *dev)

DBG("lastclose: dev=%p", dev);

/* need to restore default rotation state.. not sure if there is
* a cleaner way to restore properties to default state? Maybe
* a flag that properties should automatically be restored to
* default state on lastclose?
*/
for (i = 0; i < priv->num_crtcs; i++) {
drm_object_property_set_value(&priv->crtcs[i]->base,
priv->rotation_prop, 0);
}

for (i = 0; i < priv->num_planes; i++) {
drm_object_property_set_value(&priv->planes[i]->base,
priv->rotation_prop, 0);
}

ret = drm_fb_helper_restore_fbdev_mode(priv->fbdev);
if (ret)
DBG("failed to restore crtc mode");
Expand Down
32 changes: 30 additions & 2 deletions trunk/drivers/staging/omapdrm/omap_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,26 @@ struct omap_drm_private {
struct list_head obj_list;

bool has_dmm;

/* properties: */
struct drm_property *rotation_prop;
};

/* this should probably be in drm-core to standardize amongst drivers */
#define DRM_ROTATE_0 0
#define DRM_ROTATE_90 1
#define DRM_ROTATE_180 2
#define DRM_ROTATE_270 3
#define DRM_REFLECT_X 4
#define DRM_REFLECT_Y 5

/* parameters which describe (unrotated) coordinates of scanout within a fb: */
struct omap_drm_window {
uint32_t rotation;
int32_t crtc_x, crtc_y; /* signed because can be offscreen */
uint32_t crtc_w, crtc_h;
uint32_t src_x, src_y;
uint32_t src_w, src_h;
};

#ifdef CONFIG_DEBUG_FS
Expand Down Expand Up @@ -87,6 +107,10 @@ int omap_plane_mode_set(struct drm_plane *plane,
uint32_t src_w, uint32_t src_h);
void omap_plane_on_endwin(struct drm_plane *plane,
void (*fxn)(void *), void *arg);
void omap_plane_install_properties(struct drm_plane *plane,
struct drm_mode_object *obj);
int omap_plane_set_property(struct drm_plane *plane,
struct drm_property *property, uint64_t val);

struct drm_encoder *omap_encoder_init(struct drm_device *dev,
struct omap_overlay_manager *mgr);
Expand Down Expand Up @@ -114,8 +138,8 @@ struct drm_gem_object *omap_framebuffer_bo(struct drm_framebuffer *fb, int p);
int omap_framebuffer_replace(struct drm_framebuffer *a,
struct drm_framebuffer *b, void *arg,
void (*unpin)(void *arg, struct drm_gem_object *bo));
void omap_framebuffer_update_scanout(struct drm_framebuffer *fb, int x, int y,
struct omap_overlay_info *info);
void omap_framebuffer_update_scanout(struct drm_framebuffer *fb,
struct omap_drm_window *win, struct omap_overlay_info *info);
struct drm_connector *omap_framebuffer_get_next_connector(
struct drm_framebuffer *fb, struct drm_connector *from);
void omap_framebuffer_flush(struct drm_framebuffer *fb,
Expand Down Expand Up @@ -157,8 +181,12 @@ int omap_gem_get_pages(struct drm_gem_object *obj, struct page ***pages,
bool remap);
int omap_gem_put_pages(struct drm_gem_object *obj);
uint32_t omap_gem_flags(struct drm_gem_object *obj);
int omap_gem_rotated_paddr(struct drm_gem_object *obj, uint32_t orient,
int x, int y, dma_addr_t *paddr);
uint64_t omap_gem_mmap_offset(struct drm_gem_object *obj);
size_t omap_gem_mmap_size(struct drm_gem_object *obj);
int omap_gem_tiled_size(struct drm_gem_object *obj, uint16_t *w, uint16_t *h);
int omap_gem_tiled_stride(struct drm_gem_object *obj, uint32_t orient);

struct dma_buf * omap_gem_prime_export(struct drm_device *dev,
struct drm_gem_object *obj, int flags);
Expand Down
99 changes: 85 additions & 14 deletions trunk/drivers/staging/omapdrm/omap_fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/

#include "omap_drv.h"
#include "omap_dmm_tiler.h"

#include "drm_crtc.h"
#include "drm_crtc_helper.h"
Expand Down Expand Up @@ -137,30 +138,100 @@ static const struct drm_framebuffer_funcs omap_framebuffer_funcs = {
.dirty = omap_framebuffer_dirty,
};

static uint32_t get_linear_addr(struct plane *plane,
const struct format *format, int n, int x, int y)
{
uint32_t offset;

offset = plane->offset +
(x * format->planes[n].stride_bpp) +
(y * plane->pitch / format->planes[n].sub_y);

return plane->paddr + offset;
}

/* update ovl info for scanout, handles cases of multi-planar fb's, etc.
*/
void omap_framebuffer_update_scanout(struct drm_framebuffer *fb, int x, int y,
struct omap_overlay_info *info)
void omap_framebuffer_update_scanout(struct drm_framebuffer *fb,
struct omap_drm_window *win, struct omap_overlay_info *info)
{
struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
const struct format *format = omap_fb->format;
struct plane *plane = &omap_fb->planes[0];
unsigned int offset;
uint32_t x, y, orient = 0;

info->color_mode = format->dss_format;

info->pos_x = win->crtc_x;
info->pos_y = win->crtc_y;
info->out_width = win->crtc_w;
info->out_height = win->crtc_h;
info->width = win->src_w;
info->height = win->src_h;

x = win->src_x;
y = win->src_y;

if (omap_gem_flags(plane->bo) & OMAP_BO_TILED) {
uint32_t w = win->src_w;
uint32_t h = win->src_h;

switch (win->rotation & 0xf) {
default:
dev_err(fb->dev->dev, "invalid rotation: %02x",
(uint32_t)win->rotation);
/* fallthru to default to no rotation */
case 0:
case BIT(DRM_ROTATE_0):
orient = 0;
break;
case BIT(DRM_ROTATE_90):
orient = MASK_XY_FLIP | MASK_X_INVERT;
break;
case BIT(DRM_ROTATE_180):
orient = MASK_X_INVERT | MASK_Y_INVERT;
break;
case BIT(DRM_ROTATE_270):
orient = MASK_XY_FLIP | MASK_Y_INVERT;
break;
}

offset = plane->offset +
(x * format->planes[0].stride_bpp) +
(y * plane->pitch / format->planes[0].sub_y);
if (win->rotation & BIT(DRM_REFLECT_X))
orient ^= MASK_X_INVERT;

if (win->rotation & BIT(DRM_REFLECT_Y))
orient ^= MASK_Y_INVERT;

/* adjust x,y offset for flip/invert: */
if (orient & MASK_XY_FLIP)
swap(w, h);
if (orient & MASK_Y_INVERT)
y += h - 1;
if (orient & MASK_X_INVERT)
x += w - 1;

info->color_mode = format->dss_format;
info->paddr = plane->paddr + offset;
info->screen_width = plane->pitch / format->planes[0].stride_bpp;
omap_gem_rotated_paddr(plane->bo, orient, x, y, &info->paddr);
info->rotation_type = OMAP_DSS_ROT_TILER;
info->screen_width = omap_gem_tiled_stride(plane->bo, orient);
} else {
info->paddr = get_linear_addr(plane, format, 0, x, y);
info->rotation_type = OMAP_DSS_ROT_DMA;
info->screen_width = plane->pitch;
}

/* convert to pixels: */
info->screen_width /= format->planes[0].stride_bpp;

if (format->dss_format == OMAP_DSS_COLOR_NV12) {
plane = &omap_fb->planes[1];
offset = plane->offset +
(x * format->planes[1].stride_bpp) +
(y * plane->pitch / format->planes[1].sub_y);
info->p_uv_addr = plane->paddr + offset;

if (info->rotation_type == OMAP_DSS_ROT_TILER) {
WARN_ON(!(omap_gem_flags(plane->bo) & OMAP_BO_TILED));
omap_gem_rotated_paddr(plane->bo, orient,
x/2, y/2, &info->p_uv_addr);
} else {
info->p_uv_addr = get_linear_addr(plane, format, 1, x, y);
}
} else {
info->p_uv_addr = 0;
}
Expand Down Expand Up @@ -377,7 +448,7 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,

size = pitch * mode_cmd->height / format->planes[i].sub_y;

if (size > (bos[i]->size - mode_cmd->offsets[i])) {
if (size > (omap_gem_mmap_size(bos[i]) - mode_cmd->offsets[i])) {
dev_err(dev->dev, "provided buffer object is too small! %d < %d\n",
bos[i]->size - mode_cmd->offsets[i], size);
ret = -EINVAL;
Expand Down
Loading

0 comments on commit 13a4af2

Please sign in to comment.