Skip to content

Commit

Permalink
drm/exynos: add display-mode-check operation to exynos_mixer_ops struct
Browse files Browse the repository at this point in the history
This patch adds the display mode check operation to exynos_mixer_ops
in drm-common-hdmi. In Exynos SoCs, mixer IP can put certain restrictions
on the proposed display modes. These restriction needs to be considered
during mode negotiation, which happens immediately after edid parsing.

Both, mixer check-mode and hdmi check-timing callbacks are called one after
another and ANDed result is returned back.

Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
  • Loading branch information
Rahul Sharma authored and Inki Dae committed Feb 21, 2013
1 parent 979c0c7 commit 438c0f8
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 8 deletions.
12 changes: 12 additions & 0 deletions drivers/gpu/drm/exynos/exynos_drm_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,21 @@ static struct edid *drm_hdmi_get_edid(struct device *dev,
static int drm_hdmi_check_timing(struct device *dev, void *timing)
{
struct drm_hdmi_context *ctx = to_context(dev);
int ret = 0;

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

/*
* Both, mixer and hdmi should be able to handle the requested mode.
* If any of the two fails, return mode as BAD.
*/

if (mixer_ops && mixer_ops->check_timing)
ret = mixer_ops->check_timing(ctx->mixer_ctx->ctx, timing);

if (ret)
return ret;

if (hdmi_ops && hdmi_ops->check_timing)
return hdmi_ops->check_timing(ctx->hdmi_ctx->ctx, timing);

Expand Down
5 changes: 4 additions & 1 deletion drivers/gpu/drm/exynos/exynos_drm_hdmi.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ struct exynos_hdmi_ops {
bool (*is_connected)(void *ctx);
struct edid *(*get_edid)(void *ctx,
struct drm_connector *connector);
int (*check_timing)(void *ctx, void *timing);
int (*check_timing)(void *ctx, struct fb_videomode *timing);
int (*power_on)(void *ctx, int mode);

/* manager */
Expand All @@ -58,6 +58,9 @@ struct exynos_mixer_ops {
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);

/* display */
int (*check_timing)(void *ctx, struct fb_videomode *timing);
};

void exynos_hdmi_drv_attach(struct exynos_drm_hdmi_context *ctx);
Expand Down
13 changes: 6 additions & 7 deletions drivers/gpu/drm/exynos/exynos_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1457,21 +1457,20 @@ static int hdmi_v14_check_timing(struct fb_videomode *check_timing)
return -EINVAL;
}

static int hdmi_check_timing(void *ctx, void *timing)
static int hdmi_check_timing(void *ctx, struct fb_videomode *timing)
{
struct hdmi_context *hdata = ctx;
struct fb_videomode *check_timing = timing;

DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);

DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", check_timing->xres,
check_timing->yres, check_timing->refresh,
check_timing->vmode);
DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", timing->xres,
timing->yres, timing->refresh,
timing->vmode);

if (hdata->type == HDMI_TYPE13)
return hdmi_v13_check_timing(check_timing);
return hdmi_v13_check_timing(timing);
else
return hdmi_v14_check_timing(check_timing);
return hdmi_v14_check_timing(timing);
}

static void hdmi_set_acr(u32 freq, u8 *acr)
Expand Down

0 comments on commit 438c0f8

Please sign in to comment.