Skip to content

Commit

Permalink
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Browse files Browse the repository at this point in the history
Pull drm fixes from Dave Airlie:
 "Exynos, i915 and msm fixes and one core fix.

  exynos:
     hdmi power off and mixer issues

  msm:
     iommu, build fixes,

  i915:
     regression races and warning fixes"

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: (22 commits)
  drm/i915: vlv_prepare_pll is only needed in case of non DSI interfaces
  drm: fix NULL pointer access by wrong ioctl
  drm/exynos: enable vsync interrupt while waiting for vblank
  drm/exynos: soft reset mixer before reconfigure after power-on
  drm/exynos: allow multiple layer updates per vsync for mixer
  drm/i915: Hold the table lock whilst walking the file's idr and counting the objects in debugfs
  drm/i915: BDW: Adding Reserved PCI IDs.
  drm/i915: Only mark the ctx as initialised after a SET_CONTEXT operation
  drm/exynos: stop mixer before gating clocks during poweroff
  drm/exynos: set power state variable after enabling clocks and power
  drm/exynos: disable unused windows on apply
  drm/exynos: Fix de-registration ordering
  drm/exynos: change zero to NULL for sparse
  drm/exynos: dpi: Fix NULL pointer dereference with legacy bindings
  drm/exynos: hdmi: fix power order issue
  drm/i915: default to having backlight if VBT not available
  drm/i915: cache hw power well enabled state
  drm/msm: fix IOMMU cleanup for -EPROBE_DEFER
  drm/msm: use PAGE_ALIGNED instead of IS_ALIGNED(PAGE_SIZE)
  drm/msm/hdmi: set hdp clock rate before prepare_enable
  ...
  • Loading branch information
Linus Torvalds committed Jun 28, 2014
2 parents 3493860 + 0fcb70c commit c163b52
Show file tree
Hide file tree
Showing 26 changed files with 169 additions and 70 deletions.
3 changes: 2 additions & 1 deletion drivers/gpu/drm/drm_drv.c
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -419,8 +419,9 @@ long drm_ioctl(struct file *filp,
retcode = -EFAULT;
goto err_i1;
}
} else
} else if (cmd & IOC_OUT) {
memset(kdata, 0, usize);
}

if (ioctl->flags & DRM_UNLOCKED)
retcode = func(dev, kdata, file_priv);
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/exynos/exynos_drm_dpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ exynos_dpi_detect(struct drm_connector *connector, bool force)
{
struct exynos_dpi *ctx = connector_to_dpi(connector);

if (!ctx->panel->connector)
if (ctx->panel && !ctx->panel->connector)
drm_panel_attach(ctx->panel, &ctx->connector);

return connector_status_connected;
Expand Down
8 changes: 4 additions & 4 deletions drivers/gpu/drm/exynos/exynos_drm_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -765,24 +765,24 @@ static int exynos_drm_init(void)

return 0;

err_unregister_pd:
platform_device_unregister(exynos_drm_pdev);

err_remove_vidi:
#ifdef CONFIG_DRM_EXYNOS_VIDI
exynos_drm_remove_vidi();

err_unregister_pd:
#endif
platform_device_unregister(exynos_drm_pdev);

return ret;
}

static void exynos_drm_exit(void)
{
platform_driver_unregister(&exynos_drm_platform_driver);
#ifdef CONFIG_DRM_EXYNOS_VIDI
exynos_drm_remove_vidi();
#endif
platform_device_unregister(exynos_drm_pdev);
platform_driver_unregister(&exynos_drm_platform_driver);
}

module_init(exynos_drm_init);
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/exynos/exynos_drm_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ struct exynos_drm_display * exynos_dpi_probe(struct device *dev);
int exynos_dpi_remove(struct device *dev);
#else
static inline struct exynos_drm_display *
exynos_dpi_probe(struct device *dev) { return 0; }
exynos_dpi_probe(struct device *dev) { return NULL; }
static inline int exynos_dpi_remove(struct device *dev) { return 0; }
#endif

Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/exynos/exynos_drm_fimd.c
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,8 @@ static void fimd_apply(struct exynos_drm_manager *mgr)
win_data = &ctx->win_data[i];
if (win_data->enabled)
fimd_win_commit(mgr, i);
else
fimd_win_disable(mgr, i);
}

fimd_commit(mgr);
Expand Down
19 changes: 19 additions & 0 deletions drivers/gpu/drm/exynos/exynos_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -2090,6 +2090,11 @@ static void hdmi_poweroff(struct exynos_drm_display *display)

static void hdmi_dpms(struct exynos_drm_display *display, int mode)
{
struct hdmi_context *hdata = display->ctx;
struct drm_encoder *encoder = hdata->encoder;
struct drm_crtc *crtc = encoder->crtc;
struct drm_crtc_helper_funcs *funcs = NULL;

DRM_DEBUG_KMS("mode %d\n", mode);

switch (mode) {
Expand All @@ -2099,6 +2104,20 @@ static void hdmi_dpms(struct exynos_drm_display *display, int mode)
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
/*
* The SFRs of VP and Mixer are updated by Vertical Sync of
* Timing generator which is a part of HDMI so the sequence
* to disable TV Subsystem should be as following,
* VP -> Mixer -> HDMI
*
* Below codes will try to disable Mixer and VP(if used)
* prior to disabling HDMI.
*/
if (crtc)
funcs = crtc->helper_private;
if (funcs && funcs->dpms)
(*funcs->dpms)(crtc, mode);

hdmi_poweroff(display);
break;
default:
Expand Down
50 changes: 35 additions & 15 deletions drivers/gpu/drm/exynos/exynos_mixer.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,20 @@ static void mixer_run(struct mixer_context *ctx)
mixer_regs_dump(ctx);
}

static void mixer_stop(struct mixer_context *ctx)
{
struct mixer_resources *res = &ctx->mixer_res;
int timeout = 20;

mixer_reg_writemask(res, MXR_STATUS, 0, MXR_STATUS_REG_RUN);

while (!(mixer_reg_read(res, MXR_STATUS) & MXR_STATUS_REG_IDLE) &&
--timeout)
usleep_range(10000, 12000);

mixer_regs_dump(ctx);
}

static void vp_video_buffer(struct mixer_context *ctx, int win)
{
struct mixer_resources *res = &ctx->mixer_res;
Expand Down Expand Up @@ -497,13 +511,8 @@ static void vp_video_buffer(struct mixer_context *ctx, int win)
static void mixer_layer_update(struct mixer_context *ctx)
{
struct mixer_resources *res = &ctx->mixer_res;
u32 val;

val = mixer_reg_read(res, MXR_CFG);

/* allow one update per vsync only */
if (!(val & MXR_CFG_LAYER_UPDATE_COUNT_MASK))
mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE);
mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE);
}

static void mixer_graph_buffer(struct mixer_context *ctx, int win)
Expand Down Expand Up @@ -1010,6 +1019,8 @@ static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr)
}
mutex_unlock(&mixer_ctx->mixer_mutex);

drm_vblank_get(mgr->crtc->dev, mixer_ctx->pipe);

atomic_set(&mixer_ctx->wait_vsync_event, 1);

/*
Expand All @@ -1020,6 +1031,8 @@ static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr)
!atomic_read(&mixer_ctx->wait_vsync_event),
HZ/20))
DRM_DEBUG_KMS("vblank wait timed out.\n");

drm_vblank_put(mgr->crtc->dev, mixer_ctx->pipe);
}

static void mixer_window_suspend(struct exynos_drm_manager *mgr)
Expand Down Expand Up @@ -1061,7 +1074,7 @@ static void mixer_poweron(struct exynos_drm_manager *mgr)
mutex_unlock(&ctx->mixer_mutex);
return;
}
ctx->powered = true;

mutex_unlock(&ctx->mixer_mutex);

pm_runtime_get_sync(ctx->dev);
Expand All @@ -1072,6 +1085,12 @@ static void mixer_poweron(struct exynos_drm_manager *mgr)
clk_prepare_enable(res->sclk_mixer);
}

mutex_lock(&ctx->mixer_mutex);
ctx->powered = true;
mutex_unlock(&ctx->mixer_mutex);

mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET);

mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
mixer_win_reset(ctx);

Expand All @@ -1084,27 +1103,28 @@ static void mixer_poweroff(struct exynos_drm_manager *mgr)
struct mixer_resources *res = &ctx->mixer_res;

mutex_lock(&ctx->mixer_mutex);
if (!ctx->powered)
goto out;
if (!ctx->powered) {
mutex_unlock(&ctx->mixer_mutex);
return;
}
mutex_unlock(&ctx->mixer_mutex);

mixer_stop(ctx);
mixer_window_suspend(mgr);

ctx->int_en = mixer_reg_read(res, MXR_INT_EN);

mutex_lock(&ctx->mixer_mutex);
ctx->powered = false;
mutex_unlock(&ctx->mixer_mutex);

clk_disable_unprepare(res->mixer);
if (ctx->vp_enabled) {
clk_disable_unprepare(res->vp);
clk_disable_unprepare(res->sclk_mixer);
}

pm_runtime_put_sync(ctx->dev);

mutex_lock(&ctx->mixer_mutex);
ctx->powered = false;

out:
mutex_unlock(&ctx->mixer_mutex);
}

static void mixer_dpms(struct exynos_drm_manager *mgr, int mode)
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/exynos/regs-mixer.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
#define MXR_STATUS_BIG_ENDIAN (1 << 3)
#define MXR_STATUS_ENDIAN_MASK (1 << 3)
#define MXR_STATUS_SYNC_ENABLE (1 << 2)
#define MXR_STATUS_REG_IDLE (1 << 1)
#define MXR_STATUS_REG_RUN (1 << 0)

/* bits for MXR_CFG */
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/i915_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,9 @@ static int i915_gem_object_info(struct seq_file *m, void* data)

memset(&stats, 0, sizeof(stats));
stats.file_priv = file->driver_priv;
spin_lock(&file->table_lock);
idr_for_each(&file->object_idr, per_file_stats, &stats);
spin_unlock(&file->table_lock);
/*
* Although we have a valid reference on file->pid, that does
* not guarantee that the task_struct who called get_pid() is
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,8 @@ struct i915_power_well {
bool always_on;
/* power well enable/disable usage count */
int count;
/* cached hw enabled state */
bool hw_enabled;
unsigned long domains;
unsigned long data;
const struct i915_power_well_ops *ops;
Expand Down
8 changes: 5 additions & 3 deletions drivers/gpu/drm/i915/i915_gem_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,7 @@ static int do_switch(struct intel_engine_cs *ring,
struct intel_context *from = ring->last_context;
struct i915_hw_ppgtt *ppgtt = ctx_to_ppgtt(to);
u32 hw_flags = 0;
bool uninitialized = false;
int ret, i;

if (from != NULL && ring == &dev_priv->ring[RCS]) {
Expand Down Expand Up @@ -696,19 +697,20 @@ static int do_switch(struct intel_engine_cs *ring,
i915_gem_context_unreference(from);
}

uninitialized = !to->is_initialized && from == NULL;
to->is_initialized = true;

done:
i915_gem_context_reference(to);
ring->last_context = to;
to->last_ring = ring;

if (ring->id == RCS && !to->is_initialized && from == NULL) {
if (uninitialized) {
ret = i915_gem_render_state_init(ring);
if (ret)
DRM_ERROR("init render state: %d\n", ret);
}

to->is_initialized = true;

return 0;

unpin_out:
Expand Down
6 changes: 3 additions & 3 deletions drivers/gpu/drm/i915/intel_bios.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,9 +315,6 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
const struct bdb_lfp_backlight_data *backlight_data;
const struct bdb_lfp_backlight_data_entry *entry;

/* Err to enabling backlight if no backlight block. */
dev_priv->vbt.backlight.present = true;

backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT);
if (!backlight_data)
return;
Expand Down Expand Up @@ -1088,6 +1085,9 @@ init_vbt_defaults(struct drm_i915_private *dev_priv)

dev_priv->vbt.crt_ddc_pin = GMBUS_PORT_VGADDC;

/* Default to having backlight */
dev_priv->vbt.backlight.present = true;

/* LFP panel data */
dev_priv->vbt.lvds_dither = 1;
dev_priv->vbt.lvds_vbt = 0;
Expand Down
13 changes: 7 additions & 6 deletions drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -4564,7 +4564,10 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
if (intel_crtc->active)
return;

vlv_prepare_pll(intel_crtc);
is_dsi = intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI);

if (!is_dsi && !IS_CHERRYVIEW(dev))
vlv_prepare_pll(intel_crtc);

/* Set up the display plane register */
dspcntr = DISPPLANE_GAMMA_ENABLE;
Expand Down Expand Up @@ -4598,8 +4601,6 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
if (encoder->pre_pll_enable)
encoder->pre_pll_enable(encoder);

is_dsi = intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI);

if (!is_dsi) {
if (IS_CHERRYVIEW(dev))
chv_enable_pll(intel_crtc);
Expand Down Expand Up @@ -12411,8 +12412,8 @@ intel_display_capture_error_state(struct drm_device *dev)

for_each_pipe(i) {
error->pipe[i].power_domain_on =
intel_display_power_enabled_sw(dev_priv,
POWER_DOMAIN_PIPE(i));
intel_display_power_enabled_unlocked(dev_priv,
POWER_DOMAIN_PIPE(i));
if (!error->pipe[i].power_domain_on)
continue;

Expand Down Expand Up @@ -12447,7 +12448,7 @@ intel_display_capture_error_state(struct drm_device *dev)
enum transcoder cpu_transcoder = transcoders[i];

error->transcoder[i].power_domain_on =
intel_display_power_enabled_sw(dev_priv,
intel_display_power_enabled_unlocked(dev_priv,
POWER_DOMAIN_TRANSCODER(cpu_transcoder));
if (!error->transcoder[i].power_domain_on)
continue;
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/i915/intel_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -950,8 +950,8 @@ int intel_power_domains_init(struct drm_i915_private *);
void intel_power_domains_remove(struct drm_i915_private *);
bool intel_display_power_enabled(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain);
bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain);
bool intel_display_power_enabled_unlocked(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain);
void intel_display_power_get(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain);
void intel_display_power_put(struct drm_i915_private *dev_priv,
Expand Down
Loading

0 comments on commit c163b52

Please sign in to comment.