mirror of
https://github.com/torvalds/linux
synced 2024-09-24 13:31:12 +00:00
drm/exynos: hdmi: move mode_fixup to drm common hdmi
Currently, mode_fixup code doesn't consider the limitations of mixer as it is implemented inside the hdmi driver. Following fix, moves the mode_fixup to common drm hdmi driver. To check the mode support, it calls both, mixer and hdmi check_timing callbacks for a given resolution mode. This patch is dependent on https://patchwork.kernel.org/patch/2176021/. Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com>
This commit is contained in:
parent
6b986edfbc
commit
7ddcc7364a
|
@ -205,13 +205,45 @@ static void drm_hdmi_mode_fixup(struct device *subdrv_dev,
|
||||||
const struct drm_display_mode *mode,
|
const struct drm_display_mode *mode,
|
||||||
struct drm_display_mode *adjusted_mode)
|
struct drm_display_mode *adjusted_mode)
|
||||||
{
|
{
|
||||||
struct drm_hdmi_context *ctx = to_context(subdrv_dev);
|
struct drm_display_mode *m;
|
||||||
|
int mode_ok;
|
||||||
|
|
||||||
DRM_DEBUG_KMS("%s\n", __FILE__);
|
DRM_DEBUG_KMS("%s\n", __FILE__);
|
||||||
|
|
||||||
if (hdmi_ops && hdmi_ops->mode_fixup)
|
drm_mode_set_crtcinfo(adjusted_mode, 0);
|
||||||
hdmi_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector, mode,
|
|
||||||
adjusted_mode);
|
mode_ok = drm_hdmi_check_timing(subdrv_dev, adjusted_mode);
|
||||||
|
|
||||||
|
/* just return if user desired mode exists. */
|
||||||
|
if (mode_ok == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* otherwise, find the most suitable mode among modes and change it
|
||||||
|
* to adjusted_mode.
|
||||||
|
*/
|
||||||
|
list_for_each_entry(m, &connector->modes, head) {
|
||||||
|
mode_ok = drm_hdmi_check_timing(subdrv_dev, m);
|
||||||
|
|
||||||
|
if (mode_ok == 0) {
|
||||||
|
struct drm_mode_object base;
|
||||||
|
struct list_head head;
|
||||||
|
|
||||||
|
DRM_INFO("desired mode doesn't exist so\n");
|
||||||
|
DRM_INFO("use the most suitable mode among modes.\n");
|
||||||
|
|
||||||
|
DRM_DEBUG_KMS("Adjusted Mode: [%d]x[%d] [%d]Hz\n",
|
||||||
|
m->hdisplay, m->vdisplay, m->vrefresh);
|
||||||
|
|
||||||
|
/* preserve display mode header while copying. */
|
||||||
|
head = adjusted_mode->head;
|
||||||
|
base = adjusted_mode->base;
|
||||||
|
memcpy(adjusted_mode, m, sizeof(*m));
|
||||||
|
adjusted_mode->head = head;
|
||||||
|
adjusted_mode->base = base;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode)
|
static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode)
|
||||||
|
|
|
@ -36,9 +36,6 @@ struct exynos_hdmi_ops {
|
||||||
int (*power_on)(void *ctx, int mode);
|
int (*power_on)(void *ctx, int mode);
|
||||||
|
|
||||||
/* manager */
|
/* manager */
|
||||||
void (*mode_fixup)(void *ctx, struct drm_connector *connector,
|
|
||||||
const struct drm_display_mode *mode,
|
|
||||||
struct drm_display_mode *adjusted_mode);
|
|
||||||
void (*mode_set)(void *ctx, void *mode);
|
void (*mode_set)(void *ctx, void *mode);
|
||||||
void (*get_max_resol)(void *ctx, unsigned int *width,
|
void (*get_max_resol)(void *ctx, unsigned int *width,
|
||||||
unsigned int *height);
|
unsigned int *height);
|
||||||
|
|
|
@ -1430,52 +1430,6 @@ static void hdmi_conf_apply(struct hdmi_context *hdata)
|
||||||
hdmi_regs_dump(hdata, "start");
|
hdmi_regs_dump(hdata, "start");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
|
|
||||||
const struct drm_display_mode *mode,
|
|
||||||
struct drm_display_mode *adjusted_mode)
|
|
||||||
{
|
|
||||||
struct drm_display_mode *m;
|
|
||||||
struct hdmi_context *hdata = ctx;
|
|
||||||
int index;
|
|
||||||
|
|
||||||
DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
|
|
||||||
|
|
||||||
drm_mode_set_crtcinfo(adjusted_mode, 0);
|
|
||||||
|
|
||||||
index = hdmi_find_phy_conf(hdata, adjusted_mode->clock * 1000);
|
|
||||||
|
|
||||||
/* just return if user desired mode exists. */
|
|
||||||
if (index >= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* otherwise, find the most suitable mode among modes and change it
|
|
||||||
* to adjusted_mode.
|
|
||||||
*/
|
|
||||||
list_for_each_entry(m, &connector->modes, head) {
|
|
||||||
index = hdmi_find_phy_conf(hdata, m->clock * 1000);
|
|
||||||
|
|
||||||
if (index >= 0) {
|
|
||||||
struct drm_mode_object base;
|
|
||||||
struct list_head head;
|
|
||||||
|
|
||||||
DRM_INFO("desired mode doesn't exist so\n");
|
|
||||||
DRM_INFO("use the most suitable mode among modes.\n");
|
|
||||||
|
|
||||||
DRM_DEBUG_KMS("Adjusted Mode: [%d]x[%d] [%d]Hz\n",
|
|
||||||
m->hdisplay, m->vdisplay, m->vrefresh);
|
|
||||||
|
|
||||||
/* preserve display mode header while copying. */
|
|
||||||
head = adjusted_mode->head;
|
|
||||||
base = adjusted_mode->base;
|
|
||||||
memcpy(adjusted_mode, m, sizeof(*m));
|
|
||||||
adjusted_mode->head = head;
|
|
||||||
adjusted_mode->base = base;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hdmi_set_reg(u8 *reg_pair, int num_bytes, u32 value)
|
static void hdmi_set_reg(u8 *reg_pair, int num_bytes, u32 value)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -1816,7 +1770,6 @@ static struct exynos_hdmi_ops hdmi_ops = {
|
||||||
.check_timing = hdmi_check_timing,
|
.check_timing = hdmi_check_timing,
|
||||||
|
|
||||||
/* manager */
|
/* manager */
|
||||||
.mode_fixup = hdmi_mode_fixup,
|
|
||||||
.mode_set = hdmi_mode_set,
|
.mode_set = hdmi_mode_set,
|
||||||
.get_max_resol = hdmi_get_max_resol,
|
.get_max_resol = hdmi_get_max_resol,
|
||||||
.commit = hdmi_commit,
|
.commit = hdmi_commit,
|
||||||
|
|
Loading…
Reference in a new issue