Skip to content
This repository was archived by the owner on Oct 5, 2018. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion drivers/gpu/drm/drm_crtc_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ static void modehack_handler(struct work_struct *work)
struct drm_display_mode *mode1, *mode_first = NULL, *mode2 = NULL;
bool next = false;
char *envp[2];
int ret;

if (!modehack_set.crtc)
return;
Expand All @@ -254,6 +255,7 @@ static void modehack_handler(struct work_struct *work)
if (next) {
next = false;
mode2 = mode1;
break;
}
next = drm_mode_equal(&modehack_set.crtc->mode, mode1);
}
Expand All @@ -271,7 +273,11 @@ static void modehack_handler(struct work_struct *work)
modehack_set.num_connectors = 1;

drm_helper_connector_dpms(connector, DRM_MODE_DPMS_STANDBY);
drm_crtc_helper_set_config(&modehack_set);
ret = drm_crtc_helper_set_config(&modehack_set);
if (ret) {
modehack_set.crtc->mode = *mode2; /* skip this mode */
goto bail;
}
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);

envp[0] = "SOURCE=hotkey";
Expand Down
15 changes: 13 additions & 2 deletions drivers/gpu/drm/hisilicon/hisi_drm_ade.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,17 @@ static bool hisi_drm_crtc_mode_fixup(struct drm_crtc *crtc,
pr_info("%s: pixel clock: req %dkHz -> actual: %dkHz\n",
__func__, mode->clock, adj_mode->clock);

/* adjust 720p timings to let output more stable */
if (mode->hdisplay == 1280 && mode->vdisplay == 720 &&
mode->vrefresh == 60)
{
adj_mode->hsync_start = 1500;
adj_mode->hsync_end = 1540;
adj_mode->vsync_start = 740;
adj_mode->vsync_end = 745;
}


DRM_DEBUG_DRIVER("mode_fixup exit successfully.\n");
return true;
}
Expand All @@ -354,14 +365,14 @@ static void hisi_drm_crtc_mode_prepare(struct drm_crtc *crtc)

static int hisi_drm_crtc_mode_set(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode,
struct drm_display_mode *adj_mode,
int x, int y,
struct drm_framebuffer *old_fb)
{
struct hisi_drm_ade_crtc *crtc_ade = to_hisi_crtc(crtc);

DRM_DEBUG_DRIVER("mode_set enter successfully.\n");
crtc_ade->dmode = mode;
crtc_ade->dmode = adj_mode;
DRM_DEBUG_DRIVER("mode_set exit successfully.\n");
return 0;
}
Expand Down
108 changes: 92 additions & 16 deletions drivers/gpu/drm/hisilicon/hisi_drm_dsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ struct dsi_phy_seq_info dphy_seq_info[] = {

static struct drm_display_mode mode_720p_canned = {
.name = "720p60",
.vrefresh = 60,
.type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER,
.clock = 74250,
.hdisplay = 1280,
Expand All @@ -169,6 +170,50 @@ static struct drm_display_mode mode_720p_canned = {
.height_mm = 420,
};

/*
* 800x600@60 works well, so add to defaut modes
*/
static struct drm_display_mode mode_800x600_canned = {
.name = "800x600",
.vrefresh = 60,
.clock = 40000,
.hdisplay = 800,
.hsync_start = 840,
.hsync_end = 968,
.htotal = 1056,
.vdisplay = 600,
.vsync_start = 601,
.vsync_end = 605,
.vtotal = 628,
.type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER,
.flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC,
.width_mm = 735,
.height_mm = 420,
};

static int hisi_get_default_modes(struct drm_connector *connector)
{
struct drm_display_mode *mode;

/* 1280x720@60: 720P */
mode = drm_mode_duplicate(connector->dev, &mode_720p_canned);
if (!mode) {
DRM_ERROR("failed to create a new display mode\n");
}

drm_mode_probed_add(connector, mode);

/* 800x600@60 */
mode = drm_mode_duplicate(connector->dev, &mode_800x600_canned);
if (!mode) {
DRM_ERROR("failed to create a new display mode\n");
}

drm_mode_probed_add(connector, mode);

return 2;
}

static inline void set_reg(u8 *addr, u32 val, u32 bw, u32 bs)
{
u32 mask = (1 << bw) - 1;
Expand Down Expand Up @@ -795,14 +840,14 @@ static void hisi_drm_encoder_dpms(struct drm_encoder *encoder, int mode)
static bool
hisi_drm_encoder_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
struct drm_display_mode *adj_mode)
{
struct drm_encoder_slave_funcs *sfuncs = get_slave_funcs(encoder);
bool ret = true;

DRM_DEBUG_DRIVER("enter.\n");
if (sfuncs->mode_fixup)
ret = sfuncs->mode_fixup(encoder, mode, adjusted_mode);
ret = sfuncs->mode_fixup(encoder, mode, adj_mode);

DRM_DEBUG_DRIVER("exit success.ret=%d\n", ret);

Expand All @@ -811,25 +856,25 @@ hisi_drm_encoder_mode_fixup(struct drm_encoder *encoder,

static void hisi_drm_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
struct drm_display_mode *adj_mode)
{
struct hisi_dsi *dsi = encoder_to_dsi(encoder);
struct videomode *vm = &dsi->vm;
struct drm_encoder_slave_funcs *sfuncs = get_slave_funcs(encoder);
u32 dphy_freq_kHz;

DRM_DEBUG_DRIVER("enter.\n");
vm->pixelclock = adjusted_mode->clock;
dsi->nominal_pixel_clock_kHz = mode->clock;

vm->hactive = mode->hdisplay;
vm->vactive = mode->vdisplay;
vm->vfront_porch = mode->vsync_start - mode->vdisplay;
vm->vback_porch = mode->vtotal - mode->vsync_end;
vm->vsync_len = mode->vsync_end - mode->vsync_start;
vm->hfront_porch = mode->hsync_start - mode->hdisplay;
vm->hback_porch = mode->htotal - mode->hsync_end;
vm->hsync_len = mode->hsync_end - mode->hsync_start;
vm->pixelclock = adj_mode->clock;
dsi->nominal_pixel_clock_kHz = adj_mode->clock;

vm->hactive = adj_mode->hdisplay;
vm->vactive = adj_mode->vdisplay;
vm->vfront_porch = adj_mode->vsync_start - adj_mode->vdisplay;
vm->vback_porch = adj_mode->vtotal - adj_mode->vsync_end;
vm->vsync_len = adj_mode->vsync_end - adj_mode->vsync_start;
vm->hfront_porch = adj_mode->hsync_start - adj_mode->hdisplay;
vm->hback_porch = adj_mode->htotal - adj_mode->hsync_end;
vm->hsync_len = adj_mode->hsync_end - adj_mode->hsync_start;

dsi->lanes = 3 + !!(vm->pixelclock >= 115000);

Expand All @@ -851,7 +896,7 @@ static void hisi_drm_encoder_mode_set(struct drm_encoder *encoder,
vm->flags |= DISPLAY_FLAGS_VSYNC_LOW;

if (sfuncs->mode_set)
sfuncs->mode_set(encoder, mode, adjusted_mode);
sfuncs->mode_set(encoder, mode, adj_mode);
DRM_DEBUG_DRIVER("exit success: pixelclk=%dkHz, dphy_freq_kHz=%dkHz\n",
(u32)vm->pixelclock, dphy_freq_kHz);
}
Expand Down Expand Up @@ -906,6 +951,7 @@ static void hisi_dsi_connector_destroy(struct drm_connector *connector)
drm_connector_cleanup(connector);
}

#if 0
static int hisi_dsi_fallback_mode(struct drm_connector *connector)
{
struct drm_display_mode *mode = kmalloc(sizeof(*mode), GFP_KERNEL);
Expand All @@ -917,13 +963,14 @@ static int hisi_dsi_fallback_mode(struct drm_connector *connector)

return 0;
}
#endif

static struct drm_connector_funcs hisi_dsi_connector_funcs = {
.dpms = drm_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = hisi_dsi_detect,
.destroy = hisi_dsi_connector_destroy,
.fallback_mode = hisi_dsi_fallback_mode,
/* .fallback_mode = hisi_dsi_fallback_mode, */
};

static int hisi_dsi_get_modes(struct drm_connector *connector)
Expand All @@ -937,6 +984,10 @@ static int hisi_dsi_get_modes(struct drm_connector *connector)
DRM_DEBUG_DRIVER("enter.\n");
if (sfuncs->get_modes)
count = sfuncs->get_modes(encoder, connector);

/* always add modes which work well on most mornitors */
count += hisi_get_default_modes(connector);

DRM_DEBUG_DRIVER("exit success. count=%d\n", count);
return count;
}
Expand All @@ -959,13 +1010,38 @@ static int hisi_drm_connector_mode_valid(struct drm_connector *connector,
struct drm_encoder *encoder = &dsi->base.base;
struct drm_encoder_slave_funcs *sfuncs = get_slave_funcs(encoder);
int ret = MODE_OK;
int vrate;

if (mode->flags & DRM_MODE_FLAG_INTERLACE)
return MODE_NO_INTERLACE;

/* pixel clock support range is (1190494208/64 Hz, 1190494208Hz) */
if (mode->clock < 18602 || mode->clock > 1190494)
return MODE_CLOCK_RANGE;

if (sfuncs->mode_valid) {
ret = sfuncs->mode_valid(encoder, mode);
if (ret != MODE_OK)
return ret;
}

/*
* some work well modes which want to add prefer type
* others will clear prefer
*/
vrate = mode->vrefresh = drm_mode_vrefresh(mode);
if ((mode->hdisplay == 1920 && mode->vdisplay == 1200 && vrate == 59) ||
(mode->hdisplay == 1920 && mode->vdisplay == 1080) ||
(mode->hdisplay == 1680 && mode->vdisplay == 1050 && vrate == 59) ||
(mode->hdisplay == 1280 && mode->vdisplay == 1024 && vrate == 60) ||
(mode->hdisplay == 1280 && mode->vdisplay == 720 &&
(vrate == 60 || vrate == 59 || vrate == 50)) ||
(mode->hdisplay == 800 && mode->vdisplay == 600 && vrate == 60))
mode->type |= DRM_MODE_TYPE_PREFERRED;
else
mode->type &= ~DRM_MODE_TYPE_PREFERRED;


DRM_DEBUG_DRIVER("exit success. ret=%d\n", ret);
return ret;
}
Expand Down