Merge branch 'exynos-drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-fixes
Summary: - Use generic function to get buffer count instead of specific one. In case of Exynos DRM, There was a special case which decides pixel format of a given buffer according to planer types, which is NV12M and NV12. However, NV12M doesn't exist in drm fourcc so it removes exynos_drm_format_num_buffers() specific to Exynos DRM and use a generic function, drm_format_num_planes() instead. - Allow mixer driver to support NV21 format for Video processor. This format was already supported but we just missed DRM_FORMAT_NV21 case so this patch considers the case so that Mixer driver can handle it correctly. - Add regression fix and some code cleanups. * 'exynos-drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos: drm/exynos: dp: Lower level of EDID read success message drm/exynos: cleanup exynos_drm_plane drm/exynos: 'win' is always unsigned drm/exynos: mixer: don't dump registers under spinlock drm/exynos: Consolidate return statements in fimd_bind() drm/exynos: Constify exynos_drm_crtc_ops drm/exynos: Fix build breakage on !DRM_EXYNOS_FIMD drm/exynos: mixer: Constify platform_device_id drm/exynos: mixer: cleanup pixelformat handling drm/exynos: mixer: also allow NV21 for the video processor drm/exynos: mixer: remove buffer count handling in vp_video_buffer() drm/exynos: plane: honor buffer offset for dma_addr drm/exynos: fb: use drm_format_num_planes to get buffer count
This commit is contained in:
Коммит
f7c125a198
|
@ -91,7 +91,7 @@ static void decon_wait_for_vblank(struct exynos_drm_crtc *crtc)
|
||||||
|
|
||||||
static void decon_clear_channel(struct decon_context *ctx)
|
static void decon_clear_channel(struct decon_context *ctx)
|
||||||
{
|
{
|
||||||
int win, ch_enabled = 0;
|
unsigned int win, ch_enabled = 0;
|
||||||
|
|
||||||
DRM_DEBUG_KMS("%s\n", __FILE__);
|
DRM_DEBUG_KMS("%s\n", __FILE__);
|
||||||
|
|
||||||
|
@ -710,7 +710,7 @@ static void decon_dpms(struct exynos_drm_crtc *crtc, int mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct exynos_drm_crtc_ops decon_crtc_ops = {
|
static const struct exynos_drm_crtc_ops decon_crtc_ops = {
|
||||||
.dpms = decon_dpms,
|
.dpms = decon_dpms,
|
||||||
.mode_fixup = decon_mode_fixup,
|
.mode_fixup = decon_mode_fixup,
|
||||||
.commit = decon_commit,
|
.commit = decon_commit,
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#include <drm/bridge/ptn3460.h>
|
#include <drm/bridge/ptn3460.h>
|
||||||
|
|
||||||
#include "exynos_dp_core.h"
|
#include "exynos_dp_core.h"
|
||||||
#include "exynos_drm_fimd.h"
|
|
||||||
|
|
||||||
#define ctx_from_connector(c) container_of(c, struct exynos_dp_device, \
|
#define ctx_from_connector(c) container_of(c, struct exynos_dp_device, \
|
||||||
connector)
|
connector)
|
||||||
|
@ -196,7 +195,7 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_err(dp->dev, "EDID Read success!\n");
|
dev_dbg(dp->dev, "EDID Read success!\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1066,6 +1065,8 @@ static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
|
||||||
|
|
||||||
static void exynos_dp_poweron(struct exynos_dp_device *dp)
|
static void exynos_dp_poweron(struct exynos_dp_device *dp)
|
||||||
{
|
{
|
||||||
|
struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
|
||||||
|
|
||||||
if (dp->dpms_mode == DRM_MODE_DPMS_ON)
|
if (dp->dpms_mode == DRM_MODE_DPMS_ON)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1076,7 +1077,8 @@ static void exynos_dp_poweron(struct exynos_dp_device *dp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fimd_dp_clock_enable(dp_to_crtc(dp), true);
|
if (crtc->ops->clock_enable)
|
||||||
|
crtc->ops->clock_enable(dp_to_crtc(dp), true);
|
||||||
|
|
||||||
clk_prepare_enable(dp->clock);
|
clk_prepare_enable(dp->clock);
|
||||||
exynos_dp_phy_init(dp);
|
exynos_dp_phy_init(dp);
|
||||||
|
@ -1087,6 +1089,8 @@ static void exynos_dp_poweron(struct exynos_dp_device *dp)
|
||||||
|
|
||||||
static void exynos_dp_poweroff(struct exynos_dp_device *dp)
|
static void exynos_dp_poweroff(struct exynos_dp_device *dp)
|
||||||
{
|
{
|
||||||
|
struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
|
||||||
|
|
||||||
if (dp->dpms_mode != DRM_MODE_DPMS_ON)
|
if (dp->dpms_mode != DRM_MODE_DPMS_ON)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1102,7 +1106,8 @@ static void exynos_dp_poweroff(struct exynos_dp_device *dp)
|
||||||
exynos_dp_phy_exit(dp);
|
exynos_dp_phy_exit(dp);
|
||||||
clk_disable_unprepare(dp->clock);
|
clk_disable_unprepare(dp->clock);
|
||||||
|
|
||||||
fimd_dp_clock_enable(dp_to_crtc(dp), false);
|
if (crtc->ops->clock_enable)
|
||||||
|
crtc->ops->clock_enable(dp_to_crtc(dp), false);
|
||||||
|
|
||||||
if (dp->panel) {
|
if (dp->panel) {
|
||||||
if (drm_panel_unprepare(dp->panel))
|
if (drm_panel_unprepare(dp->panel))
|
||||||
|
|
|
@ -238,11 +238,11 @@ static struct drm_crtc_funcs exynos_crtc_funcs = {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
|
struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
|
||||||
struct drm_plane *plane,
|
struct drm_plane *plane,
|
||||||
int pipe,
|
int pipe,
|
||||||
enum exynos_drm_output_type type,
|
enum exynos_drm_output_type type,
|
||||||
struct exynos_drm_crtc_ops *ops,
|
const struct exynos_drm_crtc_ops *ops,
|
||||||
void *ctx)
|
void *ctx)
|
||||||
{
|
{
|
||||||
struct exynos_drm_crtc *exynos_crtc;
|
struct exynos_drm_crtc *exynos_crtc;
|
||||||
struct exynos_drm_private *private = drm_dev->dev_private;
|
struct exynos_drm_private *private = drm_dev->dev_private;
|
||||||
|
|
|
@ -18,11 +18,11 @@
|
||||||
#include "exynos_drm_drv.h"
|
#include "exynos_drm_drv.h"
|
||||||
|
|
||||||
struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
|
struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
|
||||||
struct drm_plane *plane,
|
struct drm_plane *plane,
|
||||||
int pipe,
|
int pipe,
|
||||||
enum exynos_drm_output_type type,
|
enum exynos_drm_output_type type,
|
||||||
struct exynos_drm_crtc_ops *ops,
|
const struct exynos_drm_crtc_ops *ops,
|
||||||
void *context);
|
void *context);
|
||||||
int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe);
|
int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe);
|
||||||
void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int pipe);
|
void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int pipe);
|
||||||
void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int pipe);
|
void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int pipe);
|
||||||
|
|
|
@ -71,13 +71,6 @@ enum exynos_drm_output_type {
|
||||||
* @dma_addr: array of bus(accessed by dma) address to the memory region
|
* @dma_addr: array of bus(accessed by dma) address to the memory region
|
||||||
* allocated for a overlay.
|
* allocated for a overlay.
|
||||||
* @zpos: order of overlay layer(z position).
|
* @zpos: order of overlay layer(z position).
|
||||||
* @index_color: if using color key feature then this value would be used
|
|
||||||
* as index color.
|
|
||||||
* @default_win: a window to be enabled.
|
|
||||||
* @color_key: color key on or off.
|
|
||||||
* @local_path: in case of lcd type, local path mode on or off.
|
|
||||||
* @transparency: transparency on or off.
|
|
||||||
* @activated: activated or not.
|
|
||||||
* @enabled: enabled or not.
|
* @enabled: enabled or not.
|
||||||
* @resume: to resume or not.
|
* @resume: to resume or not.
|
||||||
*
|
*
|
||||||
|
@ -108,13 +101,7 @@ struct exynos_drm_plane {
|
||||||
uint32_t pixel_format;
|
uint32_t pixel_format;
|
||||||
dma_addr_t dma_addr[MAX_FB_BUFFER];
|
dma_addr_t dma_addr[MAX_FB_BUFFER];
|
||||||
unsigned int zpos;
|
unsigned int zpos;
|
||||||
unsigned int index_color;
|
|
||||||
|
|
||||||
bool default_win:1;
|
|
||||||
bool color_key:1;
|
|
||||||
bool local_path:1;
|
|
||||||
bool transparency:1;
|
|
||||||
bool activated:1;
|
|
||||||
bool enabled:1;
|
bool enabled:1;
|
||||||
bool resume:1;
|
bool resume:1;
|
||||||
};
|
};
|
||||||
|
@ -181,6 +168,10 @@ struct exynos_drm_display {
|
||||||
* @win_disable: disable hardware specific overlay.
|
* @win_disable: disable hardware specific overlay.
|
||||||
* @te_handler: trigger to transfer video image at the tearing effect
|
* @te_handler: trigger to transfer video image at the tearing effect
|
||||||
* synchronization signal if there is a page flip request.
|
* synchronization signal if there is a page flip request.
|
||||||
|
* @clock_enable: optional function enabling/disabling display domain clock,
|
||||||
|
* called from exynos-dp driver before powering up (with
|
||||||
|
* 'enable' argument as true) and after powering down (with
|
||||||
|
* 'enable' as false).
|
||||||
*/
|
*/
|
||||||
struct exynos_drm_crtc;
|
struct exynos_drm_crtc;
|
||||||
struct exynos_drm_crtc_ops {
|
struct exynos_drm_crtc_ops {
|
||||||
|
@ -195,6 +186,7 @@ struct exynos_drm_crtc_ops {
|
||||||
void (*win_commit)(struct exynos_drm_crtc *crtc, unsigned int zpos);
|
void (*win_commit)(struct exynos_drm_crtc *crtc, unsigned int zpos);
|
||||||
void (*win_disable)(struct exynos_drm_crtc *crtc, unsigned int zpos);
|
void (*win_disable)(struct exynos_drm_crtc *crtc, unsigned int zpos);
|
||||||
void (*te_handler)(struct exynos_drm_crtc *crtc);
|
void (*te_handler)(struct exynos_drm_crtc *crtc);
|
||||||
|
void (*clock_enable)(struct exynos_drm_crtc *crtc, bool enable);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -221,7 +213,7 @@ struct exynos_drm_crtc {
|
||||||
unsigned int dpms;
|
unsigned int dpms;
|
||||||
wait_queue_head_t pending_flip_queue;
|
wait_queue_head_t pending_flip_queue;
|
||||||
struct drm_pending_vblank_event *event;
|
struct drm_pending_vblank_event *event;
|
||||||
struct exynos_drm_crtc_ops *ops;
|
const struct exynos_drm_crtc_ops *ops;
|
||||||
void *ctx;
|
void *ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -171,43 +171,6 @@ exynos_drm_framebuffer_init(struct drm_device *dev,
|
||||||
return &exynos_fb->fb;
|
return &exynos_fb->fb;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 exynos_drm_format_num_buffers(struct drm_mode_fb_cmd2 *mode_cmd)
|
|
||||||
{
|
|
||||||
unsigned int cnt = 0;
|
|
||||||
|
|
||||||
if (mode_cmd->pixel_format != DRM_FORMAT_NV12)
|
|
||||||
return drm_format_num_planes(mode_cmd->pixel_format);
|
|
||||||
|
|
||||||
while (cnt != MAX_FB_BUFFER) {
|
|
||||||
if (!mode_cmd->handles[cnt])
|
|
||||||
break;
|
|
||||||
cnt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* check if NV12 or NV12M.
|
|
||||||
*
|
|
||||||
* NV12
|
|
||||||
* handles[0] = base1, offsets[0] = 0
|
|
||||||
* handles[1] = base1, offsets[1] = Y_size
|
|
||||||
*
|
|
||||||
* NV12M
|
|
||||||
* handles[0] = base1, offsets[0] = 0
|
|
||||||
* handles[1] = base2, offsets[1] = 0
|
|
||||||
*/
|
|
||||||
if (cnt == 2) {
|
|
||||||
/*
|
|
||||||
* in case of NV12 format, offsets[1] is not 0 and
|
|
||||||
* handles[0] is same as handles[1].
|
|
||||||
*/
|
|
||||||
if (mode_cmd->offsets[1] &&
|
|
||||||
mode_cmd->handles[0] == mode_cmd->handles[1])
|
|
||||||
cnt = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct drm_framebuffer *
|
static struct drm_framebuffer *
|
||||||
exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
|
exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
|
||||||
struct drm_mode_fb_cmd2 *mode_cmd)
|
struct drm_mode_fb_cmd2 *mode_cmd)
|
||||||
|
@ -230,7 +193,7 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
|
||||||
|
|
||||||
drm_helper_mode_fill_fb_struct(&exynos_fb->fb, mode_cmd);
|
drm_helper_mode_fill_fb_struct(&exynos_fb->fb, mode_cmd);
|
||||||
exynos_fb->exynos_gem_obj[0] = to_exynos_gem_obj(obj);
|
exynos_fb->exynos_gem_obj[0] = to_exynos_gem_obj(obj);
|
||||||
exynos_fb->buf_cnt = exynos_drm_format_num_buffers(mode_cmd);
|
exynos_fb->buf_cnt = drm_format_num_planes(mode_cmd->pixel_format);
|
||||||
|
|
||||||
DRM_DEBUG_KMS("buf_cnt = %d\n", exynos_fb->buf_cnt);
|
DRM_DEBUG_KMS("buf_cnt = %d\n", exynos_fb->buf_cnt);
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,6 @@
|
||||||
#include "exynos_drm_crtc.h"
|
#include "exynos_drm_crtc.h"
|
||||||
#include "exynos_drm_plane.h"
|
#include "exynos_drm_plane.h"
|
||||||
#include "exynos_drm_iommu.h"
|
#include "exynos_drm_iommu.h"
|
||||||
#include "exynos_drm_fimd.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIMD stands for Fully Interactive Mobile Display and
|
* FIMD stands for Fully Interactive Mobile Display and
|
||||||
|
@ -216,7 +215,7 @@ static void fimd_wait_for_vblank(struct exynos_drm_crtc *crtc)
|
||||||
DRM_DEBUG_KMS("vblank wait timed out.\n");
|
DRM_DEBUG_KMS("vblank wait timed out.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fimd_enable_video_output(struct fimd_context *ctx, int win,
|
static void fimd_enable_video_output(struct fimd_context *ctx, unsigned int win,
|
||||||
bool enable)
|
bool enable)
|
||||||
{
|
{
|
||||||
u32 val = readl(ctx->regs + WINCON(win));
|
u32 val = readl(ctx->regs + WINCON(win));
|
||||||
|
@ -229,7 +228,8 @@ static void fimd_enable_video_output(struct fimd_context *ctx, int win,
|
||||||
writel(val, ctx->regs + WINCON(win));
|
writel(val, ctx->regs + WINCON(win));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fimd_enable_shadow_channel_path(struct fimd_context *ctx, int win,
|
static void fimd_enable_shadow_channel_path(struct fimd_context *ctx,
|
||||||
|
unsigned int win,
|
||||||
bool enable)
|
bool enable)
|
||||||
{
|
{
|
||||||
u32 val = readl(ctx->regs + SHADOWCON);
|
u32 val = readl(ctx->regs + SHADOWCON);
|
||||||
|
@ -244,7 +244,7 @@ static void fimd_enable_shadow_channel_path(struct fimd_context *ctx, int win,
|
||||||
|
|
||||||
static void fimd_clear_channel(struct fimd_context *ctx)
|
static void fimd_clear_channel(struct fimd_context *ctx)
|
||||||
{
|
{
|
||||||
int win, ch_enabled = 0;
|
unsigned int win, ch_enabled = 0;
|
||||||
|
|
||||||
DRM_DEBUG_KMS("%s\n", __FILE__);
|
DRM_DEBUG_KMS("%s\n", __FILE__);
|
||||||
|
|
||||||
|
@ -946,7 +946,24 @@ static void fimd_te_handler(struct exynos_drm_crtc *crtc)
|
||||||
drm_handle_vblank(ctx->drm_dev, ctx->pipe);
|
drm_handle_vblank(ctx->drm_dev, ctx->pipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct exynos_drm_crtc_ops fimd_crtc_ops = {
|
static void fimd_dp_clock_enable(struct exynos_drm_crtc *crtc, bool enable)
|
||||||
|
{
|
||||||
|
struct fimd_context *ctx = crtc->ctx;
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only Exynos 5250, 5260, 5410 and 542x requires enabling DP/MIE
|
||||||
|
* clock. On these SoCs the bootloader may enable it but any
|
||||||
|
* power domain off/on will reset it to disable state.
|
||||||
|
*/
|
||||||
|
if (ctx->driver_data != &exynos5_fimd_driver_data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
val = enable ? DP_MIE_CLK_DP_ENABLE : DP_MIE_CLK_DISABLE;
|
||||||
|
writel(DP_MIE_CLK_DP_ENABLE, ctx->regs + DP_MIE_CLKCON);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct exynos_drm_crtc_ops fimd_crtc_ops = {
|
||||||
.dpms = fimd_dpms,
|
.dpms = fimd_dpms,
|
||||||
.mode_fixup = fimd_mode_fixup,
|
.mode_fixup = fimd_mode_fixup,
|
||||||
.commit = fimd_commit,
|
.commit = fimd_commit,
|
||||||
|
@ -956,6 +973,7 @@ static struct exynos_drm_crtc_ops fimd_crtc_ops = {
|
||||||
.win_commit = fimd_win_commit,
|
.win_commit = fimd_win_commit,
|
||||||
.win_disable = fimd_win_disable,
|
.win_disable = fimd_win_disable,
|
||||||
.te_handler = fimd_te_handler,
|
.te_handler = fimd_te_handler,
|
||||||
|
.clock_enable = fimd_dp_clock_enable,
|
||||||
};
|
};
|
||||||
|
|
||||||
static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
|
static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
|
||||||
|
@ -1025,12 +1043,7 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
|
||||||
if (ctx->display)
|
if (ctx->display)
|
||||||
exynos_drm_create_enc_conn(drm_dev, ctx->display);
|
exynos_drm_create_enc_conn(drm_dev, ctx->display);
|
||||||
|
|
||||||
ret = fimd_iommu_attach_devices(ctx, drm_dev);
|
return fimd_iommu_attach_devices(ctx, drm_dev);
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fimd_unbind(struct device *dev, struct device *master,
|
static void fimd_unbind(struct device *dev, struct device *master,
|
||||||
|
@ -1192,24 +1205,6 @@ static int fimd_remove(struct platform_device *pdev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fimd_dp_clock_enable(struct exynos_drm_crtc *crtc, bool enable)
|
|
||||||
{
|
|
||||||
struct fimd_context *ctx = crtc->ctx;
|
|
||||||
u32 val;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Only Exynos 5250, 5260, 5410 and 542x requires enabling DP/MIE
|
|
||||||
* clock. On these SoCs the bootloader may enable it but any
|
|
||||||
* power domain off/on will reset it to disable state.
|
|
||||||
*/
|
|
||||||
if (ctx->driver_data != &exynos5_fimd_driver_data)
|
|
||||||
return;
|
|
||||||
|
|
||||||
val = enable ? DP_MIE_CLK_DP_ENABLE : DP_MIE_CLK_DISABLE;
|
|
||||||
writel(DP_MIE_CLK_DP_ENABLE, ctx->regs + DP_MIE_CLKCON);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(fimd_dp_clock_enable);
|
|
||||||
|
|
||||||
struct platform_driver fimd_driver = {
|
struct platform_driver fimd_driver = {
|
||||||
.probe = fimd_probe,
|
.probe = fimd_probe,
|
||||||
.remove = fimd_remove,
|
.remove = fimd_remove,
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2015 Samsung Electronics Co., Ltd.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the
|
|
||||||
* Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
* option) any later version.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _EXYNOS_DRM_FIMD_H_
|
|
||||||
#define _EXYNOS_DRM_FIMD_H_
|
|
||||||
|
|
||||||
extern void fimd_dp_clock_enable(struct exynos_drm_crtc *crtc, bool enable);
|
|
||||||
|
|
||||||
#endif /* _EXYNOS_DRM_FIMD_H_ */
|
|
|
@ -76,7 +76,7 @@ int exynos_check_plane(struct drm_plane *plane, struct drm_framebuffer *fb)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
exynos_plane->dma_addr[i] = buffer->dma_addr;
|
exynos_plane->dma_addr[i] = buffer->dma_addr + fb->offsets[i];
|
||||||
|
|
||||||
DRM_DEBUG_KMS("buffer: %d, dma_addr = 0x%lx\n",
|
DRM_DEBUG_KMS("buffer: %d, dma_addr = 0x%lx\n",
|
||||||
i, (unsigned long)exynos_plane->dma_addr[i]);
|
i, (unsigned long)exynos_plane->dma_addr[i]);
|
||||||
|
|
|
@ -217,7 +217,7 @@ static int vidi_ctx_initialize(struct vidi_context *ctx,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct exynos_drm_crtc_ops vidi_crtc_ops = {
|
static const struct exynos_drm_crtc_ops vidi_crtc_ops = {
|
||||||
.dpms = vidi_dpms,
|
.dpms = vidi_dpms,
|
||||||
.enable_vblank = vidi_enable_vblank,
|
.enable_vblank = vidi_enable_vblank,
|
||||||
.disable_vblank = vidi_disable_vblank,
|
.disable_vblank = vidi_disable_vblank,
|
||||||
|
|
|
@ -44,6 +44,12 @@
|
||||||
#define MIXER_WIN_NR 3
|
#define MIXER_WIN_NR 3
|
||||||
#define MIXER_DEFAULT_WIN 0
|
#define MIXER_DEFAULT_WIN 0
|
||||||
|
|
||||||
|
/* The pixelformats that are natively supported by the mixer. */
|
||||||
|
#define MXR_FORMAT_RGB565 4
|
||||||
|
#define MXR_FORMAT_ARGB1555 5
|
||||||
|
#define MXR_FORMAT_ARGB4444 6
|
||||||
|
#define MXR_FORMAT_ARGB8888 7
|
||||||
|
|
||||||
struct mixer_resources {
|
struct mixer_resources {
|
||||||
int irq;
|
int irq;
|
||||||
void __iomem *mixer_regs;
|
void __iomem *mixer_regs;
|
||||||
|
@ -327,7 +333,8 @@ static void mixer_cfg_rgb_fmt(struct mixer_context *ctx, unsigned int height)
|
||||||
mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_RGB_FMT_MASK);
|
mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_RGB_FMT_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mixer_cfg_layer(struct mixer_context *ctx, int win, bool enable)
|
static void mixer_cfg_layer(struct mixer_context *ctx, unsigned int win,
|
||||||
|
bool enable)
|
||||||
{
|
{
|
||||||
struct mixer_resources *res = &ctx->mixer_res;
|
struct mixer_resources *res = &ctx->mixer_res;
|
||||||
u32 val = enable ? ~0 : 0;
|
u32 val = enable ? ~0 : 0;
|
||||||
|
@ -359,8 +366,6 @@ static void mixer_run(struct mixer_context *ctx)
|
||||||
struct mixer_resources *res = &ctx->mixer_res;
|
struct mixer_resources *res = &ctx->mixer_res;
|
||||||
|
|
||||||
mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_REG_RUN);
|
mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_REG_RUN);
|
||||||
|
|
||||||
mixer_regs_dump(ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mixer_stop(struct mixer_context *ctx)
|
static void mixer_stop(struct mixer_context *ctx)
|
||||||
|
@ -373,16 +378,13 @@ static void mixer_stop(struct mixer_context *ctx)
|
||||||
while (!(mixer_reg_read(res, MXR_STATUS) & MXR_STATUS_REG_IDLE) &&
|
while (!(mixer_reg_read(res, MXR_STATUS) & MXR_STATUS_REG_IDLE) &&
|
||||||
--timeout)
|
--timeout)
|
||||||
usleep_range(10000, 12000);
|
usleep_range(10000, 12000);
|
||||||
|
|
||||||
mixer_regs_dump(ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vp_video_buffer(struct mixer_context *ctx, int win)
|
static void vp_video_buffer(struct mixer_context *ctx, unsigned int win)
|
||||||
{
|
{
|
||||||
struct mixer_resources *res = &ctx->mixer_res;
|
struct mixer_resources *res = &ctx->mixer_res;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct exynos_drm_plane *plane;
|
struct exynos_drm_plane *plane;
|
||||||
unsigned int buf_num = 1;
|
|
||||||
dma_addr_t luma_addr[2], chroma_addr[2];
|
dma_addr_t luma_addr[2], chroma_addr[2];
|
||||||
bool tiled_mode = false;
|
bool tiled_mode = false;
|
||||||
bool crcb_mode = false;
|
bool crcb_mode = false;
|
||||||
|
@ -393,27 +395,18 @@ static void vp_video_buffer(struct mixer_context *ctx, int win)
|
||||||
switch (plane->pixel_format) {
|
switch (plane->pixel_format) {
|
||||||
case DRM_FORMAT_NV12:
|
case DRM_FORMAT_NV12:
|
||||||
crcb_mode = false;
|
crcb_mode = false;
|
||||||
buf_num = 2;
|
|
||||||
break;
|
break;
|
||||||
/* TODO: single buffer format NV12, NV21 */
|
case DRM_FORMAT_NV21:
|
||||||
|
crcb_mode = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
/* ignore pixel format at disable time */
|
|
||||||
if (!plane->dma_addr[0])
|
|
||||||
break;
|
|
||||||
|
|
||||||
DRM_ERROR("pixel format for vp is wrong [%d].\n",
|
DRM_ERROR("pixel format for vp is wrong [%d].\n",
|
||||||
plane->pixel_format);
|
plane->pixel_format);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf_num == 2) {
|
luma_addr[0] = plane->dma_addr[0];
|
||||||
luma_addr[0] = plane->dma_addr[0];
|
chroma_addr[0] = plane->dma_addr[1];
|
||||||
chroma_addr[0] = plane->dma_addr[1];
|
|
||||||
} else {
|
|
||||||
luma_addr[0] = plane->dma_addr[0];
|
|
||||||
chroma_addr[0] = plane->dma_addr[0]
|
|
||||||
+ (plane->pitch * plane->fb_height);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plane->scan_flag & DRM_MODE_FLAG_INTERLACE) {
|
if (plane->scan_flag & DRM_MODE_FLAG_INTERLACE) {
|
||||||
ctx->interlace = true;
|
ctx->interlace = true;
|
||||||
|
@ -484,6 +477,7 @@ static void vp_video_buffer(struct mixer_context *ctx, int win)
|
||||||
mixer_vsync_set_update(ctx, true);
|
mixer_vsync_set_update(ctx, true);
|
||||||
spin_unlock_irqrestore(&res->reg_slock, flags);
|
spin_unlock_irqrestore(&res->reg_slock, flags);
|
||||||
|
|
||||||
|
mixer_regs_dump(ctx);
|
||||||
vp_regs_dump(ctx);
|
vp_regs_dump(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,7 +512,7 @@ fail:
|
||||||
return -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mixer_graph_buffer(struct mixer_context *ctx, int win)
|
static void mixer_graph_buffer(struct mixer_context *ctx, unsigned int win)
|
||||||
{
|
{
|
||||||
struct mixer_resources *res = &ctx->mixer_res;
|
struct mixer_resources *res = &ctx->mixer_res;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -531,20 +525,27 @@ static void mixer_graph_buffer(struct mixer_context *ctx, int win)
|
||||||
|
|
||||||
plane = &ctx->planes[win];
|
plane = &ctx->planes[win];
|
||||||
|
|
||||||
#define RGB565 4
|
switch (plane->pixel_format) {
|
||||||
#define ARGB1555 5
|
case DRM_FORMAT_XRGB4444:
|
||||||
#define ARGB4444 6
|
fmt = MXR_FORMAT_ARGB4444;
|
||||||
#define ARGB8888 7
|
break;
|
||||||
|
|
||||||
switch (plane->bpp) {
|
case DRM_FORMAT_XRGB1555:
|
||||||
case 16:
|
fmt = MXR_FORMAT_ARGB1555;
|
||||||
fmt = ARGB4444;
|
|
||||||
break;
|
break;
|
||||||
case 32:
|
|
||||||
fmt = ARGB8888;
|
case DRM_FORMAT_RGB565:
|
||||||
|
fmt = MXR_FORMAT_RGB565;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DRM_FORMAT_XRGB8888:
|
||||||
|
case DRM_FORMAT_ARGB8888:
|
||||||
|
fmt = MXR_FORMAT_ARGB8888;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fmt = ARGB8888;
|
DRM_DEBUG_KMS("pixelformat unsupported by mixer\n");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if mixer supports requested scaling setup */
|
/* check if mixer supports requested scaling setup */
|
||||||
|
@ -617,6 +618,8 @@ static void mixer_graph_buffer(struct mixer_context *ctx, int win)
|
||||||
|
|
||||||
mixer_vsync_set_update(ctx, true);
|
mixer_vsync_set_update(ctx, true);
|
||||||
spin_unlock_irqrestore(&res->reg_slock, flags);
|
spin_unlock_irqrestore(&res->reg_slock, flags);
|
||||||
|
|
||||||
|
mixer_regs_dump(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vp_win_reset(struct mixer_context *ctx)
|
static void vp_win_reset(struct mixer_context *ctx)
|
||||||
|
@ -1070,6 +1073,7 @@ static void mixer_poweroff(struct mixer_context *ctx)
|
||||||
mutex_unlock(&ctx->mixer_mutex);
|
mutex_unlock(&ctx->mixer_mutex);
|
||||||
|
|
||||||
mixer_stop(ctx);
|
mixer_stop(ctx);
|
||||||
|
mixer_regs_dump(ctx);
|
||||||
mixer_window_suspend(ctx);
|
mixer_window_suspend(ctx);
|
||||||
|
|
||||||
ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
|
ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
|
||||||
|
@ -1126,7 +1130,7 @@ int mixer_check_mode(struct drm_display_mode *mode)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct exynos_drm_crtc_ops mixer_crtc_ops = {
|
static const struct exynos_drm_crtc_ops mixer_crtc_ops = {
|
||||||
.dpms = mixer_dpms,
|
.dpms = mixer_dpms,
|
||||||
.enable_vblank = mixer_enable_vblank,
|
.enable_vblank = mixer_enable_vblank,
|
||||||
.disable_vblank = mixer_disable_vblank,
|
.disable_vblank = mixer_disable_vblank,
|
||||||
|
@ -1156,7 +1160,7 @@ static struct mixer_drv_data exynos4210_mxr_drv_data = {
|
||||||
.has_sclk = 1,
|
.has_sclk = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct platform_device_id mixer_driver_types[] = {
|
static const struct platform_device_id mixer_driver_types[] = {
|
||||||
{
|
{
|
||||||
.name = "s5p-mixer",
|
.name = "s5p-mixer",
|
||||||
.driver_data = (unsigned long)&exynos4210_mxr_drv_data,
|
.driver_data = (unsigned long)&exynos4210_mxr_drv_data,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче