Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 269757
b: refs/heads/master
c: 19c8b83
h: refs/heads/master
i:
  269755: 5b31c25
v: v3
  • Loading branch information
Inki Dae authored and Dave Airlie committed Oct 18, 2011
1 parent 8747a16 commit 18b9109
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 104 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: 6fcbef7a50b2f618376b65845a92cde3efc4a131
refs/heads/master: 19c8b8343d9cb9674fa47103bf2a4abb43757e65
3 changes: 3 additions & 0 deletions trunk/drivers/gpu/drm/exynos/exynos_drm_buf.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ struct exynos_drm_buf_entry {
struct exynos_drm_buf_entry *exynos_drm_buf_create(struct drm_device *dev,
unsigned int size);

/* get physical memory information of a drm framebuffer. */
struct exynos_drm_buf_entry *exynos_drm_fb_get_buf(struct drm_framebuffer *fb);

/* remove allocated physical memory. */
void exynos_drm_buf_destroy(struct drm_device *dev,
struct exynos_drm_buf_entry *entry);
Expand Down
101 changes: 62 additions & 39 deletions trunk/drivers/gpu/drm/exynos/exynos_drm_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,28 @@
#include "exynos_drm_drv.h"
#include "exynos_drm_fb.h"
#include "exynos_drm_encoder.h"
#include "exynos_drm_buf.h"

#define to_exynos_crtc(x) container_of(x, struct exynos_drm_crtc,\
drm_crtc)

/*
* @fb_x: horizontal position from framebuffer base
* @fb_y: vertical position from framebuffer base
* @base_x: horizontal position from screen base
* @base_y: vertical position from screen base
* @crtc_w: width of crtc
* @crtc_h: height of crtc
* Exynos specific crtc postion structure.
*
* @fb_x: offset x on a framebuffer to be displyed
* - the unit is screen coordinates.
* @fb_y: offset y on a framebuffer to be displayed
* - the unit is screen coordinates.
* @crtc_x: offset x on hardware screen.
* @crtc_y: offset y on hardware screen.
* @crtc_w: width of hardware screen.
* @crtc_h: height of hardware screen.
*/
struct exynos_drm_crtc_pos {
unsigned int fb_x;
unsigned int fb_y;
unsigned int base_x;
unsigned int base_y;
unsigned int crtc_x;
unsigned int crtc_y;
unsigned int crtc_w;
unsigned int crtc_h;
};
Expand Down Expand Up @@ -83,42 +88,56 @@ void exynos_drm_crtc_apply(struct drm_crtc *crtc)
exynos_drm_fn_encoder(crtc, NULL, exynos_drm_encoder_crtc_commit);
}

static void exynos_drm_overlay_update(struct exynos_drm_overlay *overlay,
static int exynos_drm_overlay_update(struct exynos_drm_overlay *overlay,
struct drm_framebuffer *fb,
struct drm_display_mode *mode,
struct exynos_drm_crtc_pos *pos)
{
struct exynos_drm_buffer_info buffer_info;
unsigned int actual_w = pos->crtc_w;
unsigned int actual_h = pos->crtc_h;
unsigned int hw_w;
unsigned int hw_h;

/* update buffer address of framebuffer. */
exynos_drm_fb_update_buf_off(fb, pos->fb_x, pos->fb_y, &buffer_info);
overlay->paddr = buffer_info.paddr;
overlay->vaddr = buffer_info.vaddr;

hw_w = mode->hdisplay - pos->base_x;
hw_h = mode->vdisplay - pos->base_y;

if (actual_w > hw_w)
actual_w = hw_w;
if (actual_h > hw_h)
actual_h = hw_h;

overlay->offset_x = pos->base_x;
overlay->offset_y = pos->base_y;
overlay->width = actual_w;
overlay->height = actual_h;
struct exynos_drm_buf_entry *entry;
unsigned int actual_w;
unsigned int actual_h;

entry = exynos_drm_fb_get_buf(fb);
if (!entry) {
DRM_LOG_KMS("entry is null.\n");
return -EFAULT;
}

overlay->paddr = entry->paddr;
overlay->vaddr = entry->vaddr;

DRM_DEBUG_KMS("vaddr = 0x%lx, paddr = 0x%lx\n",
(unsigned long)overlay->vaddr,
(unsigned long)overlay->paddr);

actual_w = min((mode->hdisplay - pos->crtc_x), pos->crtc_w);
actual_h = min((mode->vdisplay - pos->crtc_y), pos->crtc_h);

/* set drm framebuffer data. */
overlay->fb_x = pos->fb_x;
overlay->fb_y = pos->fb_y;
overlay->fb_width = fb->width;
overlay->fb_height = fb->height;
overlay->bpp = fb->bits_per_pixel;
overlay->pitch = fb->pitch;

/* set overlay range to be displayed. */
overlay->crtc_x = pos->crtc_x;
overlay->crtc_y = pos->crtc_y;
overlay->crtc_width = actual_w;
overlay->crtc_height = actual_h;

/* set drm mode data. */
overlay->mode_width = mode->hdisplay;
overlay->mode_height = mode->vdisplay;
overlay->refresh = mode->vrefresh;
overlay->scan_flag = mode->flags;

DRM_DEBUG_KMS("overlay : offset_x/y(%d,%d), width/height(%d,%d)",
overlay->offset_x, overlay->offset_y,
overlay->width, overlay->height);
overlay->crtc_x, overlay->crtc_y,
overlay->crtc_width, overlay->crtc_height);

overlay->buf_offsize = fb->width - actual_w;
overlay->line_size = actual_w;
return 0;
}

static int exynos_drm_crtc_update(struct drm_crtc *crtc)
Expand All @@ -136,14 +155,18 @@ static int exynos_drm_crtc_update(struct drm_crtc *crtc)
overlay = &exynos_crtc->overlay;

memset(&pos, 0, sizeof(struct exynos_drm_crtc_pos));

/* it means the offset of framebuffer to be displayed. */
pos.fb_x = crtc->x;
pos.fb_y = crtc->y;

/* OSD position to be displayed. */
pos.crtc_x = 0;
pos.crtc_y = 0;
pos.crtc_w = fb->width - crtc->x;
pos.crtc_h = fb->height - crtc->y;

exynos_drm_overlay_update(overlay, crtc->fb, mode, &pos);

return 0;
return exynos_drm_overlay_update(overlay, crtc->fb, mode, &pos);
}

static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
Expand Down
41 changes: 28 additions & 13 deletions trunk/drivers/gpu/drm/exynos/exynos_drm_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,26 @@ struct exynos_drm_overlay_ops {
/*
* Exynos drm common overlay structure.
*
* @offset_x: offset to x position.
* @offset_y: offset to y position.
* @width: window width.
* @height: window height.
* @fb_x: offset x on a framebuffer to be displayed.
* - the unit is screen coordinates.
* @fb_y: offset y on a framebuffer to be displayed.
* - the unit is screen coordinates.
* @fb_width: width of a framebuffer.
* @fb_height: height of a framebuffer.
* @crtc_x: offset x on hardware screen.
* @crtc_y: offset y on hardware screen.
* @crtc_width: window width to be displayed (hardware screen).
* @crtc_height: window height to be displayed (hardware screen).
* @mode_width: width of screen mode.
* @mode_height: height of screen mode.
* @refresh: refresh rate.
* @scan_flag: interlace or progressive way.
* (it could be DRM_MODE_FLAG_*)
* @bpp: pixel size.(in bit)
* @paddr: bus(accessed by dma) physical memory address to this overlay
* and this is physically continuous.
* @vaddr: virtual memory addresss to this overlay.
* @buf_off: start offset of framebuffer to be displayed.
* @buf_offsize: this value has result from
* (framebuffer width - display width) * bpp.
* @line_size: line size to this overlay memory in bytes.
* @default_win: a window to be enabled.
* @color_key: color key on or off.
* @index_color: if using color key feature then this value would be used
Expand All @@ -87,16 +95,23 @@ struct exynos_drm_overlay_ops {
* to hardware specific overlay info.
*/
struct exynos_drm_overlay {
unsigned int offset_x;
unsigned int offset_y;
unsigned int width;
unsigned int height;
unsigned int fb_x;
unsigned int fb_y;
unsigned int fb_width;
unsigned int fb_height;
unsigned int crtc_x;
unsigned int crtc_y;
unsigned int crtc_width;
unsigned int crtc_height;
unsigned int mode_width;
unsigned int mode_height;
unsigned int refresh;
unsigned int scan_flag;
unsigned int bpp;
unsigned int pitch;
dma_addr_t paddr;
void __iomem *vaddr;
unsigned int buf_off;
unsigned int buf_offsize;
unsigned int line_size;

bool default_win;
bool color_key;
Expand Down
20 changes: 7 additions & 13 deletions trunk/drivers/gpu/drm/exynos/exynos_drm_fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,28 +220,22 @@ struct drm_framebuffer *exynos_drm_fb_create(struct drm_device *dev,
return exynos_drm_fb_init(file_priv, dev, mode_cmd);
}

void exynos_drm_fb_update_buf_off(struct drm_framebuffer *fb,
unsigned int x, unsigned int y,
struct exynos_drm_buffer_info *info)
struct exynos_drm_buf_entry *exynos_drm_fb_get_buf(struct drm_framebuffer *fb)
{
struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
struct exynos_drm_buf_entry *entry;
unsigned long offset;

DRM_DEBUG_KMS("%s\n", __FILE__);

offset = x * (fb->bits_per_pixel >> 3);
offset += y * fb->pitch;

entry = exynos_fb->entry;
if (!entry)
return NULL;

info->base_addr = entry->paddr;
info->vaddr = entry->vaddr + offset;
info->paddr = entry->paddr + offset;
DRM_DEBUG_KMS("vaddr = 0x%lx, paddr = 0x%lx\n",
(unsigned long)entry->vaddr,
(unsigned long)entry->paddr);

DRM_DEBUG_KMS("updated vaddr = 0x%lx, paddr = 0x%lx, offset = 0x%x\n",
(unsigned long)info->vaddr, (unsigned long)info->paddr,
(unsigned int)offset);
return entry;
}

static struct drm_mode_config_funcs exynos_drm_mode_config_funcs = {
Expand Down
10 changes: 0 additions & 10 deletions trunk/drivers/gpu/drm/exynos/exynos_drm_fb.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,6 @@
#ifndef _EXYNOS_DRM_FB_H_
#define _EXYNOS_DRM_FB_H

struct exynos_drm_buffer_info {
unsigned long base_addr;
dma_addr_t paddr;
void __iomem *vaddr;
};

void exynos_drm_fb_update_buf_off(struct drm_framebuffer *fb,
unsigned int x, unsigned int y,
struct exynos_drm_buffer_info *info);

struct drm_framebuffer *exynos_drm_fb_create(struct drm_device *dev,
struct drm_file *filp,
struct drm_mode_fb_cmd *mode_cmd);
Expand Down
31 changes: 20 additions & 11 deletions trunk/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

#include "exynos_drm_drv.h"
#include "exynos_drm_fb.h"
#include "exynos_drm_buf.h"

#define MAX_CONNECTOR 4
#define PREFERRED_BPP 32
Expand Down Expand Up @@ -83,16 +84,17 @@ static struct fb_ops exynos_drm_fb_ops = {
.fb_setcmap = drm_fb_helper_setcmap,
};

static void exynos_drm_fbdev_update(struct drm_fb_helper *helper,
static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
struct drm_framebuffer *fb,
unsigned int fb_width,
unsigned int fb_height)
{
struct fb_info *fbi = helper->fbdev;
struct drm_device *dev = helper->dev;
struct exynos_drm_fbdev *exynos_fb = to_exynos_fbdev(helper);
struct exynos_drm_buffer_info buffer_info;
struct exynos_drm_buf_entry *entry;
unsigned int size = fb_width * fb_height * (fb->bits_per_pixel >> 3);
unsigned long offset;

DRM_DEBUG_KMS("%s\n", __FILE__);

Expand All @@ -101,15 +103,22 @@ static void exynos_drm_fbdev_update(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);

exynos_drm_fb_update_buf_off(fb, fbi->var.xoffset, fbi->var.yoffset,
&buffer_info);
entry = exynos_drm_fb_get_buf(fb);
if (!entry) {
DRM_LOG_KMS("entry is null.\n");
return -EFAULT;
}

dev->mode_config.fb_base = buffer_info.base_addr;
offset = fbi->var.xoffset * (fb->bits_per_pixel >> 3);
offset += fbi->var.yoffset * fb->pitch;

fbi->screen_base = buffer_info.vaddr;
dev->mode_config.fb_base = entry->paddr;
fbi->screen_base = entry->vaddr + offset;
fbi->fix.smem_start = entry->paddr + offset;
fbi->screen_size = size;
fbi->fix.smem_start = buffer_info.paddr;
fbi->fix.smem_len = size;

return 0;
}

static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
Expand Down Expand Up @@ -162,8 +171,10 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
goto out;
}

exynos_drm_fbdev_update(helper, helper->fb, sizes->fb_width,
ret = exynos_drm_fbdev_update(helper, helper->fb, sizes->fb_width,
sizes->fb_height);
if (ret < 0)
fb_dealloc_cmap(&fbi->cmap);

/*
* if failed, all resources allocated above would be released by
Expand Down Expand Up @@ -224,10 +235,8 @@ static int exynos_drm_fbdev_recreate(struct drm_fb_helper *helper,
}

helper->fb = exynos_fbdev->fb;
exynos_drm_fbdev_update(helper, helper->fb, sizes->fb_width,
return exynos_drm_fbdev_update(helper, helper->fb, sizes->fb_width,
sizes->fb_height);

return 0;
}

static int exynos_drm_fbdev_probe(struct drm_fb_helper *helper,
Expand Down
Loading

0 comments on commit 18b9109

Please sign in to comment.