提交 173fa4ec 编写于 作者: D Dave Airlie

Merge branch 'exynos-drm-fixes' of...

Merge branch 'exynos-drm-fixes' of git://git.infradead.org/users/kmpark/linux-samsung into drm-intel-fixes

* 'exynos-drm-fixes' of git://git.infradead.org/users/kmpark/linux-samsung:
  drm/exynos: fixed exynos broken ioctl
  drm/exynos: fix to pointer manager member of struct exynos_drm_subdrv
  drm/exynos: fix struct for operation callback functions to driver name
  drm/exynos: use define instead of default_win member in struct mixer_context
  drm/exynos: rename s/HDMI_OVERLAY_NUMBER/MIXER_WIN_NR
  drm/exynos: remove unused codes in hdmi and mixer
  drm/exynos: remove unnecessary type conversion of hdmi and mixer
  drm/exynos: add format list of plane
  drm/exynos: fixed duplicated page allocation bug.
  drm/exynos: fixed page align and code clean.
......@@ -34,14 +34,14 @@
static int lowlevel_buffer_allocate(struct drm_device *dev,
unsigned int flags, struct exynos_drm_gem_buf *buf)
{
dma_addr_t start_addr, end_addr;
dma_addr_t start_addr;
unsigned int npages, page_size, i = 0;
struct scatterlist *sgl;
int ret = 0;
DRM_DEBUG_KMS("%s\n", __FILE__);
if (flags & EXYNOS_BO_NONCONTIG) {
if (IS_NONCONTIG_BUFFER(flags)) {
DRM_DEBUG_KMS("not support allocation type.\n");
return -EINVAL;
}
......@@ -52,13 +52,13 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
}
if (buf->size >= SZ_1M) {
npages = (buf->size >> SECTION_SHIFT) + 1;
npages = buf->size >> SECTION_SHIFT;
page_size = SECTION_SIZE;
} else if (buf->size >= SZ_64K) {
npages = (buf->size >> 16) + 1;
npages = buf->size >> 16;
page_size = SZ_64K;
} else {
npages = (buf->size >> PAGE_SHIFT) + 1;
npages = buf->size >> PAGE_SHIFT;
page_size = PAGE_SIZE;
}
......@@ -76,26 +76,13 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
return -ENOMEM;
}
buf->kvaddr = dma_alloc_writecombine(dev->dev, buf->size,
&buf->dma_addr, GFP_KERNEL);
if (!buf->kvaddr) {
DRM_ERROR("failed to allocate buffer.\n");
ret = -ENOMEM;
goto err1;
}
start_addr = buf->dma_addr;
end_addr = buf->dma_addr + buf->size;
buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL);
if (!buf->pages) {
DRM_ERROR("failed to allocate pages.\n");
ret = -ENOMEM;
goto err2;
}
start_addr = buf->dma_addr;
end_addr = buf->dma_addr + buf->size;
buf->kvaddr = dma_alloc_writecombine(dev->dev, buf->size,
&buf->dma_addr, GFP_KERNEL);
if (!buf->kvaddr) {
DRM_ERROR("failed to allocate buffer.\n");
ret = -ENOMEM;
goto err1;
}
buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL);
if (!buf->pages) {
......@@ -105,23 +92,17 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
}
sgl = buf->sgt->sgl;
start_addr = buf->dma_addr;
while (i < npages) {
buf->pages[i] = phys_to_page(start_addr);
sg_set_page(sgl, buf->pages[i], page_size, 0);
sg_dma_address(sgl) = start_addr;
start_addr += page_size;
if (end_addr - start_addr < page_size)
break;
sgl = sg_next(sgl);
i++;
}
buf->pages[i] = phys_to_page(start_addr);
sgl = sg_next(sgl);
sg_set_page(sgl, buf->pages[i+1], end_addr - start_addr, 0);
DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n",
(unsigned long)buf->kvaddr,
(unsigned long)buf->dma_addr,
......@@ -150,7 +131,7 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev,
* non-continuous memory would be released by exynos
* gem framework.
*/
if (flags & EXYNOS_BO_NONCONTIG) {
if (IS_NONCONTIG_BUFFER(flags)) {
DRM_DEBUG_KMS("not support allocation type.\n");
return;
}
......
......@@ -54,16 +54,18 @@ static int exynos_drm_subdrv_probe(struct drm_device *dev,
*
* P.S. note that this driver is considered for modularization.
*/
ret = subdrv->probe(dev, subdrv->manager.dev);
ret = subdrv->probe(dev, subdrv->dev);
if (ret)
return ret;
}
if (subdrv->is_local)
if (!subdrv->manager)
return 0;
subdrv->manager->dev = subdrv->dev;
/* create and initialize a encoder for this sub driver. */
encoder = exynos_drm_encoder_create(dev, &subdrv->manager,
encoder = exynos_drm_encoder_create(dev, subdrv->manager,
(1 << MAX_CRTC) - 1);
if (!encoder) {
DRM_ERROR("failed to create encoder\n");
......@@ -186,7 +188,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file)
list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
if (subdrv->open) {
ret = subdrv->open(dev, subdrv->manager.dev, file);
ret = subdrv->open(dev, subdrv->dev, file);
if (ret)
goto err;
}
......@@ -197,7 +199,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file)
err:
list_for_each_entry_reverse(subdrv, &subdrv->list, list) {
if (subdrv->close)
subdrv->close(dev, subdrv->manager.dev, file);
subdrv->close(dev, subdrv->dev, file);
}
return ret;
}
......@@ -209,7 +211,7 @@ void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file)
list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
if (subdrv->close)
subdrv->close(dev, subdrv->manager.dev, file);
subdrv->close(dev, subdrv->dev, file);
}
}
EXPORT_SYMBOL_GPL(exynos_drm_subdrv_close);
......@@ -225,24 +225,25 @@ struct exynos_drm_private {
* Exynos drm sub driver structure.
*
* @list: sub driver has its own list object to register to exynos drm driver.
* @dev: pointer to device object for subdrv device driver.
* @drm_dev: pointer to drm_device and this pointer would be set
* when sub driver calls exynos_drm_subdrv_register().
* @is_local: appear encoder and connector disrelated device.
* @manager: subdrv has its own manager to control a hardware appropriately
* and we can access a hardware drawing on this manager.
* @probe: this callback would be called by exynos drm driver after
* subdrv is registered to it.
* @remove: this callback is used to release resources created
* by probe callback.
* @open: this would be called with drm device file open.
* @close: this would be called with drm device file close.
* @manager: subdrv has its own manager to control a hardware appropriately
* and we can access a hardware drawing on this manager.
* @encoder: encoder object owned by this sub driver.
* @connector: connector object owned by this sub driver.
*/
struct exynos_drm_subdrv {
struct list_head list;
struct device *dev;
struct drm_device *drm_dev;
bool is_local;
struct exynos_drm_manager *manager;
int (*probe)(struct drm_device *drm_dev, struct device *dev);
void (*remove)(struct drm_device *dev);
......@@ -251,7 +252,6 @@ struct exynos_drm_subdrv {
void (*close)(struct drm_device *drm_dev, struct device *dev,
struct drm_file *file);
struct exynos_drm_manager manager;
struct drm_encoder *encoder;
struct drm_connector *connector;
};
......
......@@ -172,7 +172,7 @@ static void fimd_dpms(struct device *subdrv_dev, int mode)
static void fimd_apply(struct device *subdrv_dev)
{
struct fimd_context *ctx = get_fimd_context(subdrv_dev);
struct exynos_drm_manager *mgr = &ctx->subdrv.manager;
struct exynos_drm_manager *mgr = ctx->subdrv.manager;
struct exynos_drm_manager_ops *mgr_ops = mgr->ops;
struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops;
struct fimd_win_data *win_data;
......@@ -577,6 +577,13 @@ static struct exynos_drm_overlay_ops fimd_overlay_ops = {
.disable = fimd_win_disable,
};
static struct exynos_drm_manager fimd_manager = {
.pipe = -1,
.ops = &fimd_manager_ops,
.overlay_ops = &fimd_overlay_ops,
.display_ops = &fimd_display_ops,
};
static void fimd_finish_pageflip(struct drm_device *drm_dev, int crtc)
{
struct exynos_drm_private *dev_priv = drm_dev->dev_private;
......@@ -628,7 +635,7 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
struct fimd_context *ctx = (struct fimd_context *)dev_id;
struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
struct drm_device *drm_dev = subdrv->drm_dev;
struct exynos_drm_manager *manager = &subdrv->manager;
struct exynos_drm_manager *manager = subdrv->manager;
u32 val;
val = readl(ctx->regs + VIDINTCON1);
......@@ -744,7 +751,7 @@ static void fimd_clear_win(struct fimd_context *ctx, int win)
static int fimd_power_on(struct fimd_context *ctx, bool enable)
{
struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
struct device *dev = subdrv->manager.dev;
struct device *dev = subdrv->dev;
DRM_DEBUG_KMS("%s\n", __FILE__);
......@@ -867,13 +874,10 @@ static int __devinit fimd_probe(struct platform_device *pdev)
subdrv = &ctx->subdrv;
subdrv->dev = dev;
subdrv->manager = &fimd_manager;
subdrv->probe = fimd_subdrv_probe;
subdrv->remove = fimd_subdrv_remove;
subdrv->manager.pipe = -1;
subdrv->manager.ops = &fimd_manager_ops;
subdrv->manager.overlay_ops = &fimd_overlay_ops;
subdrv->manager.display_ops = &fimd_display_ops;
subdrv->manager.dev = dev;
mutex_init(&ctx->lock);
......
......@@ -56,9 +56,28 @@ static unsigned int convert_to_vm_err_msg(int msg)
return out_msg;
}
static unsigned int mask_gem_flags(unsigned int flags)
static int check_gem_flags(unsigned int flags)
{
return flags &= EXYNOS_BO_NONCONTIG;
if (flags & ~(EXYNOS_BO_MASK)) {
DRM_ERROR("invalid flags.\n");
return -EINVAL;
}
return 0;
}
static unsigned long roundup_gem_size(unsigned long size, unsigned int flags)
{
if (!IS_NONCONTIG_BUFFER(flags)) {
if (size >= SZ_1M)
return roundup(size, SECTION_SIZE);
else if (size >= SZ_64K)
return roundup(size, SZ_64K);
else
goto out;
}
out:
return roundup(size, PAGE_SIZE);
}
static struct page **exynos_gem_get_pages(struct drm_gem_object *obj,
......@@ -319,10 +338,17 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
struct exynos_drm_gem_buf *buf;
int ret;
size = roundup(size, PAGE_SIZE);
DRM_DEBUG_KMS("%s: size = 0x%lx\n", __FILE__, size);
if (!size) {
DRM_ERROR("invalid size.\n");
return ERR_PTR(-EINVAL);
}
flags = mask_gem_flags(flags);
size = roundup_gem_size(size, flags);
DRM_DEBUG_KMS("%s\n", __FILE__);
ret = check_gem_flags(flags);
if (ret)
return ERR_PTR(ret);
buf = exynos_drm_init_buf(dev, size);
if (!buf)
......@@ -331,7 +357,7 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
exynos_gem_obj = exynos_drm_gem_init(dev, size);
if (!exynos_gem_obj) {
ret = -ENOMEM;
goto err;
goto err_fini_buf;
}
exynos_gem_obj->buffer = buf;
......@@ -347,18 +373,19 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
ret = exynos_drm_gem_get_pages(&exynos_gem_obj->base);
if (ret < 0) {
drm_gem_object_release(&exynos_gem_obj->base);
goto err;
goto err_fini_buf;
}
} else {
ret = exynos_drm_alloc_buf(dev, buf, flags);
if (ret < 0) {
drm_gem_object_release(&exynos_gem_obj->base);
goto err;
goto err_fini_buf;
}
}
return exynos_gem_obj;
err:
err_fini_buf:
exynos_drm_fini_buf(dev, buf);
return ERR_PTR(ret);
}
......
......@@ -29,6 +29,8 @@
#define to_exynos_gem_obj(x) container_of(x,\
struct exynos_drm_gem_obj, base)
#define IS_NONCONTIG_BUFFER(f) (f & EXYNOS_BO_NONCONTIG)
/*
* exynos drm gem buffer structure.
*
......
......@@ -30,9 +30,8 @@
struct drm_hdmi_context, subdrv);
/* these callback points shoud be set by specific drivers. */
static struct exynos_hdmi_display_ops *hdmi_display_ops;
static struct exynos_hdmi_manager_ops *hdmi_manager_ops;
static struct exynos_hdmi_overlay_ops *hdmi_overlay_ops;
static struct exynos_hdmi_ops *hdmi_ops;
static struct exynos_mixer_ops *mixer_ops;
struct drm_hdmi_context {
struct exynos_drm_subdrv subdrv;
......@@ -40,31 +39,20 @@ struct drm_hdmi_context {
struct exynos_drm_hdmi_context *mixer_ctx;
};
void exynos_drm_display_ops_register(struct exynos_hdmi_display_ops
*display_ops)
void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops)
{
DRM_DEBUG_KMS("%s\n", __FILE__);
if (display_ops)
hdmi_display_ops = display_ops;
if (ops)
hdmi_ops = ops;
}
void exynos_drm_manager_ops_register(struct exynos_hdmi_manager_ops
*manager_ops)
void exynos_mixer_ops_register(struct exynos_mixer_ops *ops)
{
DRM_DEBUG_KMS("%s\n", __FILE__);
if (manager_ops)
hdmi_manager_ops = manager_ops;
}
void exynos_drm_overlay_ops_register(struct exynos_hdmi_overlay_ops
*overlay_ops)
{
DRM_DEBUG_KMS("%s\n", __FILE__);
if (overlay_ops)
hdmi_overlay_ops = overlay_ops;
if (ops)
mixer_ops = ops;
}
static bool drm_hdmi_is_connected(struct device *dev)
......@@ -73,8 +61,8 @@ static bool drm_hdmi_is_connected(struct device *dev)
DRM_DEBUG_KMS("%s\n", __FILE__);
if (hdmi_display_ops && hdmi_display_ops->is_connected)
return hdmi_display_ops->is_connected(ctx->hdmi_ctx->ctx);
if (hdmi_ops && hdmi_ops->is_connected)
return hdmi_ops->is_connected(ctx->hdmi_ctx->ctx);
return false;
}
......@@ -86,9 +74,9 @@ static int drm_hdmi_get_edid(struct device *dev,
DRM_DEBUG_KMS("%s\n", __FILE__);
if (hdmi_display_ops && hdmi_display_ops->get_edid)
return hdmi_display_ops->get_edid(ctx->hdmi_ctx->ctx,
connector, edid, len);
if (hdmi_ops && hdmi_ops->get_edid)
return hdmi_ops->get_edid(ctx->hdmi_ctx->ctx, connector, edid,
len);
return 0;
}
......@@ -99,9 +87,8 @@ static int drm_hdmi_check_timing(struct device *dev, void *timing)
DRM_DEBUG_KMS("%s\n", __FILE__);
if (hdmi_display_ops && hdmi_display_ops->check_timing)
return hdmi_display_ops->check_timing(ctx->hdmi_ctx->ctx,
timing);
if (hdmi_ops && hdmi_ops->check_timing)
return hdmi_ops->check_timing(ctx->hdmi_ctx->ctx, timing);
return 0;
}
......@@ -112,8 +99,8 @@ static int drm_hdmi_power_on(struct device *dev, int mode)
DRM_DEBUG_KMS("%s\n", __FILE__);
if (hdmi_display_ops && hdmi_display_ops->power_on)
return hdmi_display_ops->power_on(ctx->hdmi_ctx->ctx, mode);
if (hdmi_ops && hdmi_ops->power_on)
return hdmi_ops->power_on(ctx->hdmi_ctx->ctx, mode);
return 0;
}
......@@ -130,13 +117,13 @@ static int drm_hdmi_enable_vblank(struct device *subdrv_dev)
{
struct drm_hdmi_context *ctx = to_context(subdrv_dev);
struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
struct exynos_drm_manager *manager = &subdrv->manager;
struct exynos_drm_manager *manager = subdrv->manager;
DRM_DEBUG_KMS("%s\n", __FILE__);
if (hdmi_overlay_ops && hdmi_overlay_ops->enable_vblank)
return hdmi_overlay_ops->enable_vblank(ctx->mixer_ctx->ctx,
manager->pipe);
if (mixer_ops && mixer_ops->enable_vblank)
return mixer_ops->enable_vblank(ctx->mixer_ctx->ctx,
manager->pipe);
return 0;
}
......@@ -147,8 +134,8 @@ static void drm_hdmi_disable_vblank(struct device *subdrv_dev)
DRM_DEBUG_KMS("%s\n", __FILE__);
if (hdmi_overlay_ops && hdmi_overlay_ops->disable_vblank)
return hdmi_overlay_ops->disable_vblank(ctx->mixer_ctx->ctx);
if (mixer_ops && mixer_ops->disable_vblank)
return mixer_ops->disable_vblank(ctx->mixer_ctx->ctx);
}
static void drm_hdmi_mode_fixup(struct device *subdrv_dev,
......@@ -160,9 +147,9 @@ static void drm_hdmi_mode_fixup(struct device *subdrv_dev,
DRM_DEBUG_KMS("%s\n", __FILE__);
if (hdmi_manager_ops && hdmi_manager_ops->mode_fixup)
hdmi_manager_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector,
mode, adjusted_mode);
if (hdmi_ops && hdmi_ops->mode_fixup)
hdmi_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector, mode,
adjusted_mode);
}
static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode)
......@@ -171,8 +158,8 @@ static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode)
DRM_DEBUG_KMS("%s\n", __FILE__);
if (hdmi_manager_ops && hdmi_manager_ops->mode_set)
hdmi_manager_ops->mode_set(ctx->hdmi_ctx->ctx, mode);
if (hdmi_ops && hdmi_ops->mode_set)
hdmi_ops->mode_set(ctx->hdmi_ctx->ctx, mode);
}
static void drm_hdmi_get_max_resol(struct device *subdrv_dev,
......@@ -182,9 +169,8 @@ static void drm_hdmi_get_max_resol(struct device *subdrv_dev,
DRM_DEBUG_KMS("%s\n", __FILE__);
if (hdmi_manager_ops && hdmi_manager_ops->get_max_resol)
hdmi_manager_ops->get_max_resol(ctx->hdmi_ctx->ctx, width,
height);
if (hdmi_ops && hdmi_ops->get_max_resol)
hdmi_ops->get_max_resol(ctx->hdmi_ctx->ctx, width, height);
}
static void drm_hdmi_commit(struct device *subdrv_dev)
......@@ -193,8 +179,8 @@ static void drm_hdmi_commit(struct device *subdrv_dev)
DRM_DEBUG_KMS("%s\n", __FILE__);
if (hdmi_manager_ops && hdmi_manager_ops->commit)
hdmi_manager_ops->commit(ctx->hdmi_ctx->ctx);
if (hdmi_ops && hdmi_ops->commit)
hdmi_ops->commit(ctx->hdmi_ctx->ctx);
}
static void drm_hdmi_dpms(struct device *subdrv_dev, int mode)
......@@ -209,8 +195,8 @@ static void drm_hdmi_dpms(struct device *subdrv_dev, int mode)
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
if (hdmi_manager_ops && hdmi_manager_ops->disable)
hdmi_manager_ops->disable(ctx->hdmi_ctx->ctx);
if (hdmi_ops && hdmi_ops->disable)
hdmi_ops->disable(ctx->hdmi_ctx->ctx);
break;
default:
DRM_DEBUG_KMS("unkown dps mode: %d\n", mode);
......@@ -235,8 +221,8 @@ static void drm_mixer_mode_set(struct device *subdrv_dev,
DRM_DEBUG_KMS("%s\n", __FILE__);
if (hdmi_overlay_ops && hdmi_overlay_ops->win_mode_set)
hdmi_overlay_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay);
if (mixer_ops && mixer_ops->win_mode_set)
mixer_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay);
}
static void drm_mixer_commit(struct device *subdrv_dev, int zpos)
......@@ -245,8 +231,8 @@ static void drm_mixer_commit(struct device *subdrv_dev, int zpos)
DRM_DEBUG_KMS("%s\n", __FILE__);
if (hdmi_overlay_ops && hdmi_overlay_ops->win_commit)
hdmi_overlay_ops->win_commit(ctx->mixer_ctx->ctx, zpos);
if (mixer_ops && mixer_ops->win_commit)
mixer_ops->win_commit(ctx->mixer_ctx->ctx, zpos);
}
static void drm_mixer_disable(struct device *subdrv_dev, int zpos)
......@@ -255,8 +241,8 @@ static void drm_mixer_disable(struct device *subdrv_dev, int zpos)
DRM_DEBUG_KMS("%s\n", __FILE__);
if (hdmi_overlay_ops && hdmi_overlay_ops->win_disable)
hdmi_overlay_ops->win_disable(ctx->mixer_ctx->ctx, zpos);
if (mixer_ops && mixer_ops->win_disable)
mixer_ops->win_disable(ctx->mixer_ctx->ctx, zpos);
}
static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = {
......@@ -265,6 +251,12 @@ static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = {
.disable = drm_mixer_disable,
};
static struct exynos_drm_manager hdmi_manager = {
.pipe = -1,
.ops = &drm_hdmi_manager_ops,
.overlay_ops = &drm_hdmi_overlay_ops,
.display_ops = &drm_hdmi_display_ops,
};
static int hdmi_subdrv_probe(struct drm_device *drm_dev,
struct device *dev)
......@@ -332,12 +324,9 @@ static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev)
subdrv = &ctx->subdrv;
subdrv->dev = dev;
subdrv->manager = &hdmi_manager;
subdrv->probe = hdmi_subdrv_probe;
subdrv->manager.pipe = -1;
subdrv->manager.ops = &drm_hdmi_manager_ops;
subdrv->manager.overlay_ops = &drm_hdmi_overlay_ops;
subdrv->manager.display_ops = &drm_hdmi_display_ops;
subdrv->manager.dev = dev;
platform_set_drvdata(pdev, subdrv);
......
......@@ -38,15 +38,15 @@ struct exynos_drm_hdmi_context {
void *ctx;
};
struct exynos_hdmi_display_ops {
struct exynos_hdmi_ops {
/* display */
bool (*is_connected)(void *ctx);
int (*get_edid)(void *ctx, struct drm_connector *connector,
u8 *edid, int len);
int (*check_timing)(void *ctx, void *timing);
int (*power_on)(void *ctx, int mode);
};
struct exynos_hdmi_manager_ops {
/* manager */
void (*mode_fixup)(void *ctx, struct drm_connector *connector,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
......@@ -57,22 +57,17 @@ struct exynos_hdmi_manager_ops {
void (*disable)(void *ctx);
};
struct exynos_hdmi_overlay_ops {
struct exynos_mixer_ops {
/* manager */
int (*enable_vblank)(void *ctx, int pipe);
void (*disable_vblank)(void *ctx);
/* overlay */
void (*win_mode_set)(void *ctx, struct exynos_drm_overlay *overlay);
void (*win_commit)(void *ctx, int zpos);
void (*win_disable)(void *ctx, int zpos);
};
extern struct platform_driver hdmi_driver;
extern struct platform_driver mixer_driver;
void exynos_drm_display_ops_register(struct exynos_hdmi_display_ops
*display_ops);
void exynos_drm_manager_ops_register(struct exynos_hdmi_manager_ops
*manager_ops);
void exynos_drm_overlay_ops_register(struct exynos_hdmi_overlay_ops
*overlay_ops);
void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops);
void exynos_mixer_ops_register(struct exynos_mixer_ops *ops);
#endif
......@@ -24,6 +24,10 @@ struct exynos_plane {
static const uint32_t formats[] = {
DRM_FORMAT_XRGB8888,
DRM_FORMAT_ARGB8888,
DRM_FORMAT_NV12,
DRM_FORMAT_NV12M,
DRM_FORMAT_NV12MT,
};
static int
......
......@@ -199,7 +199,7 @@ static void vidi_dpms(struct device *subdrv_dev, int mode)
static void vidi_apply(struct device *subdrv_dev)
{
struct vidi_context *ctx = get_vidi_context(subdrv_dev);
struct exynos_drm_manager *mgr = &ctx->subdrv.manager;
struct exynos_drm_manager *mgr = ctx->subdrv.manager;
struct exynos_drm_manager_ops *mgr_ops = mgr->ops;
struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops;
struct vidi_win_data *win_data;
......@@ -374,6 +374,13 @@ static struct exynos_drm_overlay_ops vidi_overlay_ops = {
.disable = vidi_win_disable,
};
static struct exynos_drm_manager vidi_manager = {
.pipe = -1,
.ops = &vidi_manager_ops,
.overlay_ops = &vidi_overlay_ops,
.display_ops = &vidi_display_ops,
};
static void vidi_finish_pageflip(struct drm_device *drm_dev, int crtc)
{
struct exynos_drm_private *dev_priv = drm_dev->dev_private;
......@@ -425,7 +432,7 @@ static void vidi_fake_vblank_handler(struct work_struct *work)
struct vidi_context *ctx = container_of(work, struct vidi_context,
work);
struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
struct exynos_drm_manager *manager = &subdrv->manager;
struct exynos_drm_manager *manager = subdrv->manager;
if (manager->pipe < 0)
return;
......@@ -471,7 +478,7 @@ static void vidi_subdrv_remove(struct drm_device *drm_dev)
static int vidi_power_on(struct vidi_context *ctx, bool enable)
{
struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
struct device *dev = subdrv->manager.dev;
struct device *dev = subdrv->dev;
DRM_DEBUG_KMS("%s\n", __FILE__);
......@@ -611,13 +618,10 @@ static int __devinit vidi_probe(struct platform_device *pdev)
ctx->raw_edid = (struct edid *)fake_edid_info;
subdrv = &ctx->subdrv;
subdrv->dev = dev;
subdrv->manager = &vidi_manager;
subdrv->probe = vidi_subdrv_probe;
subdrv->remove = vidi_subdrv_remove;
subdrv->manager.pipe = -1;
subdrv->manager.ops = &vidi_manager_ops;
subdrv->manager.overlay_ops = &vidi_overlay_ops;
subdrv->manager.display_ops = &vidi_display_ops;
subdrv->manager.dev = dev;
mutex_init(&ctx->lock);
......
......@@ -40,7 +40,6 @@
#include "exynos_hdmi.h"
#define HDMI_OVERLAY_NUMBER 3
#define MAX_WIDTH 1920
#define MAX_HEIGHT 1080
#define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev))
......@@ -1194,7 +1193,7 @@ static int hdmi_conf_index(struct hdmi_context *hdata,
static bool hdmi_is_connected(void *ctx)
{
struct hdmi_context *hdata = (struct hdmi_context *)ctx;
struct hdmi_context *hdata = ctx;
u32 val = hdmi_reg_read(hdata, HDMI_HPD_STATUS);
if (val)
......@@ -1207,7 +1206,7 @@ static int hdmi_get_edid(void *ctx, struct drm_connector *connector,
u8 *edid, int len)
{
struct edid *raw_edid;
struct hdmi_context *hdata = (struct hdmi_context *)ctx;
struct hdmi_context *hdata = ctx;
DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
......@@ -1275,7 +1274,7 @@ static int hdmi_v14_check_timing(struct fb_videomode *check_timing)
static int hdmi_check_timing(void *ctx, void *timing)
{
struct hdmi_context *hdata = (struct hdmi_context *)ctx;
struct hdmi_context *hdata = ctx;
struct fb_videomode *check_timing = timing;
DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
......@@ -1312,13 +1311,6 @@ static int hdmi_display_power_on(void *ctx, int mode)
return 0;
}
static struct exynos_hdmi_display_ops display_ops = {
.is_connected = hdmi_is_connected,
.get_edid = hdmi_get_edid,
.check_timing = hdmi_check_timing,
.power_on = hdmi_display_power_on,
};
static void hdmi_set_acr(u32 freq, u8 *acr)
{
u32 n, cts;
......@@ -1914,7 +1906,7 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
struct drm_display_mode *adjusted_mode)
{
struct drm_display_mode *m;
struct hdmi_context *hdata = (struct hdmi_context *)ctx;
struct hdmi_context *hdata = ctx;
int index;
DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
......@@ -1951,7 +1943,7 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
static void hdmi_mode_set(void *ctx, void *mode)
{
struct hdmi_context *hdata = (struct hdmi_context *)ctx;
struct hdmi_context *hdata = ctx;
int conf_idx;
DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
......@@ -1974,7 +1966,7 @@ static void hdmi_get_max_resol(void *ctx, unsigned int *width,
static void hdmi_commit(void *ctx)
{
struct hdmi_context *hdata = (struct hdmi_context *)ctx;
struct hdmi_context *hdata = ctx;
DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
......@@ -1985,7 +1977,7 @@ static void hdmi_commit(void *ctx)
static void hdmi_disable(void *ctx)
{
struct hdmi_context *hdata = (struct hdmi_context *)ctx;
struct hdmi_context *hdata = ctx;
DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
......@@ -1996,7 +1988,14 @@ static void hdmi_disable(void *ctx)
}
}
static struct exynos_hdmi_manager_ops manager_ops = {
static struct exynos_hdmi_ops hdmi_ops = {
/* display */
.is_connected = hdmi_is_connected,
.get_edid = hdmi_get_edid,
.check_timing = hdmi_check_timing,
.power_on = hdmi_display_power_on,
/* manager */
.mode_fixup = hdmi_mode_fixup,
.mode_set = hdmi_mode_set,
.get_max_resol = hdmi_get_max_resol,
......@@ -2020,7 +2019,7 @@ static void hdmi_hotplug_func(struct work_struct *work)
static irqreturn_t hdmi_irq_handler(int irq, void *arg)
{
struct exynos_drm_hdmi_context *ctx = arg;
struct hdmi_context *hdata = (struct hdmi_context *)ctx->ctx;
struct hdmi_context *hdata = ctx->ctx;
u32 intc_flag;
intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG);
......@@ -2173,7 +2172,7 @@ static int hdmi_runtime_suspend(struct device *dev)
DRM_DEBUG_KMS("%s\n", __func__);
hdmi_resource_poweroff((struct hdmi_context *)ctx->ctx);
hdmi_resource_poweroff(ctx->ctx);
return 0;
}
......@@ -2184,7 +2183,7 @@ static int hdmi_runtime_resume(struct device *dev)
DRM_DEBUG_KMS("%s\n", __func__);
hdmi_resource_poweron((struct hdmi_context *)ctx->ctx);
hdmi_resource_poweron(ctx->ctx);
return 0;
}
......@@ -2322,8 +2321,7 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
hdata->irq = res->start;
/* register specific callbacks to common hdmi. */
exynos_drm_display_ops_register(&display_ops);
exynos_drm_manager_ops_register(&manager_ops);
exynos_hdmi_ops_register(&hdmi_ops);
hdmi_resource_poweron(hdata);
......@@ -2351,7 +2349,7 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
static int __devexit hdmi_remove(struct platform_device *pdev)
{
struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev);
struct hdmi_context *hdata = (struct hdmi_context *)ctx->ctx;
struct hdmi_context *hdata = ctx->ctx;
DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
......
......@@ -37,7 +37,8 @@
#include "exynos_drm_drv.h"
#include "exynos_drm_hdmi.h"
#define HDMI_OVERLAY_NUMBER 3
#define MIXER_WIN_NR 3
#define MIXER_DEFAULT_WIN 0
#define get_mixer_context(dev) platform_get_drvdata(to_platform_device(dev))
......@@ -75,16 +76,12 @@ struct mixer_resources {
};
struct mixer_context {
struct fb_videomode *default_timing;
unsigned int default_win;
unsigned int default_bpp;
unsigned int irq;
int pipe;
bool interlace;
bool vp_enabled;
struct mixer_resources mixer_res;
struct hdmi_win_data win_data[HDMI_OVERLAY_NUMBER];
struct hdmi_win_data win_data[MIXER_WIN_NR];
};
static const u8 filter_y_horiz_tap8[] = {
......@@ -643,9 +640,9 @@ static void mixer_win_mode_set(void *ctx,
win = overlay->zpos;
if (win == DEFAULT_ZPOS)
win = mixer_ctx->default_win;
win = MIXER_DEFAULT_WIN;
if (win < 0 || win > HDMI_OVERLAY_NUMBER) {
if (win < 0 || win > MIXER_WIN_NR) {
DRM_ERROR("overlay plane[%d] is wrong\n", win);
return;
}
......@@ -683,9 +680,9 @@ static void mixer_win_commit(void *ctx, int zpos)
DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
if (win == DEFAULT_ZPOS)
win = mixer_ctx->default_win;
win = MIXER_DEFAULT_WIN;
if (win < 0 || win > HDMI_OVERLAY_NUMBER) {
if (win < 0 || win > MIXER_WIN_NR) {
DRM_ERROR("overlay plane[%d] is wrong\n", win);
return;
}
......@@ -706,9 +703,9 @@ static void mixer_win_disable(void *ctx, int zpos)
DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
if (win == DEFAULT_ZPOS)
win = mixer_ctx->default_win;
win = MIXER_DEFAULT_WIN;
if (win < 0 || win > HDMI_OVERLAY_NUMBER) {
if (win < 0 || win > MIXER_WIN_NR) {
DRM_ERROR("overlay plane[%d] is wrong\n", win);
return;
}
......@@ -722,9 +719,12 @@ static void mixer_win_disable(void *ctx, int zpos)
spin_unlock_irqrestore(&res->reg_slock, flags);
}
static struct exynos_hdmi_overlay_ops overlay_ops = {
static struct exynos_mixer_ops mixer_ops = {
/* manager */
.enable_vblank = mixer_enable_vblank,
.disable_vblank = mixer_disable_vblank,
/* overlay */
.win_mode_set = mixer_win_mode_set,
.win_commit = mixer_win_commit,
.win_disable = mixer_win_disable,
......@@ -771,8 +771,7 @@ static void mixer_finish_pageflip(struct drm_device *drm_dev, int crtc)
static irqreturn_t mixer_irq_handler(int irq, void *arg)
{
struct exynos_drm_hdmi_context *drm_hdmi_ctx = arg;
struct mixer_context *ctx =
(struct mixer_context *)drm_hdmi_ctx->ctx;
struct mixer_context *ctx = drm_hdmi_ctx->ctx;
struct mixer_resources *res = &ctx->mixer_res;
u32 val, val_base;
......@@ -902,7 +901,7 @@ static int mixer_runtime_resume(struct device *dev)
DRM_DEBUG_KMS("resume - start\n");
mixer_resource_poweron((struct mixer_context *)ctx->ctx);
mixer_resource_poweron(ctx->ctx);
return 0;
}
......@@ -913,7 +912,7 @@ static int mixer_runtime_suspend(struct device *dev)
DRM_DEBUG_KMS("suspend - start\n");
mixer_resource_poweroff((struct mixer_context *)ctx->ctx);
mixer_resource_poweroff(ctx->ctx);
return 0;
}
......@@ -926,8 +925,7 @@ static const struct dev_pm_ops mixer_pm_ops = {
static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx,
struct platform_device *pdev)
{
struct mixer_context *mixer_ctx =
(struct mixer_context *)ctx->ctx;
struct mixer_context *mixer_ctx = ctx->ctx;
struct device *dev = &pdev->dev;
struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
struct resource *res;
......@@ -1076,7 +1074,7 @@ static int __devinit mixer_probe(struct platform_device *pdev)
goto fail;
/* register specific callback point to common hdmi. */
exynos_drm_overlay_ops_register(&overlay_ops);
exynos_mixer_ops_register(&mixer_ops);
mixer_resource_poweron(ctx);
......@@ -1093,7 +1091,7 @@ static int mixer_remove(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct exynos_drm_hdmi_context *drm_hdmi_ctx =
platform_get_drvdata(pdev);
struct mixer_context *ctx = (struct mixer_context *)drm_hdmi_ctx->ctx;
struct mixer_context *ctx = drm_hdmi_ctx->ctx;
dev_info(dev, "remove successful\n");
......
......@@ -85,7 +85,7 @@ struct drm_exynos_gem_mmap {
struct drm_exynos_vidi_connection {
unsigned int connection;
unsigned int extensions;
uint64_t *edid;
uint64_t edid;
};
struct drm_exynos_plane_set_zpos {
......@@ -96,7 +96,8 @@ struct drm_exynos_plane_set_zpos {
/* memory type definitions. */
enum e_drm_exynos_gem_mem_type {
/* Physically Non-Continuous memory. */
EXYNOS_BO_NONCONTIG = 1 << 0
EXYNOS_BO_NONCONTIG = 1 << 0,
EXYNOS_BO_MASK = EXYNOS_BO_NONCONTIG
};
#define DRM_EXYNOS_GEM_CREATE 0x00
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册