drm/i915: Add new GET_PIPE_FROM_CRTC_ID ioctl.
This allows userlevel code to discover the pipe number corresponding to a given CRTC ID. This is necessary for doing pipe-specific operations such as waiting for vblank on a given CRTC. Failure to use the right pipe mapping can result in GPU hangs, or at least failure to actually sync to vblank. Signed-off-by: Carl Worth <cworth@cworth.org> [anholt: Style touchups from review] Signed-off-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
Родитель
9d2949a4cd
Коммит
08d7b3d1ed
|
@ -1358,6 +1358,7 @@ struct drm_ioctl_desc i915_ioctls[] = {
|
||||||
DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0),
|
DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0),
|
||||||
DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0),
|
DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0),
|
||||||
DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, 0),
|
DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, 0),
|
||||||
|
DRM_IOCTL_DEF(DRM_I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
|
int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
|
||||||
|
|
|
@ -1804,6 +1804,37 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
|
||||||
|
struct drm_file *file_priv)
|
||||||
|
{
|
||||||
|
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||||
|
struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data;
|
||||||
|
struct drm_crtc *crtc = NULL;
|
||||||
|
int pipe = -1;
|
||||||
|
|
||||||
|
if (!dev_priv) {
|
||||||
|
DRM_ERROR("called with no initialization\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||||
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||||
|
if (crtc->base.id == pipe_from_crtc_id->crtc_id) {
|
||||||
|
pipe = intel_crtc->pipe;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pipe == -1) {
|
||||||
|
DRM_ERROR("no such CRTC id\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pipe_from_crtc_id->pipe = pipe;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe)
|
struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe)
|
||||||
{
|
{
|
||||||
struct drm_crtc *crtc = NULL;
|
struct drm_crtc *crtc = NULL;
|
||||||
|
|
|
@ -125,6 +125,8 @@ extern struct drm_encoder *intel_best_encoder(struct drm_connector *connector);
|
||||||
|
|
||||||
extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
|
extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
|
||||||
struct drm_crtc *crtc);
|
struct drm_crtc *crtc);
|
||||||
|
int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
|
||||||
|
struct drm_file *file_priv);
|
||||||
extern void intel_wait_for_vblank(struct drm_device *dev);
|
extern void intel_wait_for_vblank(struct drm_device *dev);
|
||||||
extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe);
|
extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe);
|
||||||
extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
|
extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
|
||||||
|
|
|
@ -184,6 +184,7 @@ typedef struct _drm_i915_sarea {
|
||||||
#define DRM_I915_GEM_GET_TILING 0x22
|
#define DRM_I915_GEM_GET_TILING 0x22
|
||||||
#define DRM_I915_GEM_GET_APERTURE 0x23
|
#define DRM_I915_GEM_GET_APERTURE 0x23
|
||||||
#define DRM_I915_GEM_MMAP_GTT 0x24
|
#define DRM_I915_GEM_MMAP_GTT 0x24
|
||||||
|
#define DRM_I915_GET_PIPE_FROM_CRTC_ID 0x25
|
||||||
|
|
||||||
#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
|
#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
|
||||||
#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
|
#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
|
||||||
|
@ -219,6 +220,7 @@ typedef struct _drm_i915_sarea {
|
||||||
#define DRM_IOCTL_I915_GEM_SET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling)
|
#define DRM_IOCTL_I915_GEM_SET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling)
|
||||||
#define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling)
|
#define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling)
|
||||||
#define DRM_IOCTL_I915_GEM_GET_APERTURE DRM_IOR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_APERTURE, struct drm_i915_gem_get_aperture)
|
#define DRM_IOCTL_I915_GEM_GET_APERTURE DRM_IOR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_APERTURE, struct drm_i915_gem_get_aperture)
|
||||||
|
#define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_intel_get_pipe_from_crtc_id)
|
||||||
|
|
||||||
/* Allow drivers to submit batchbuffers directly to hardware, relying
|
/* Allow drivers to submit batchbuffers directly to hardware, relying
|
||||||
* on the security mechanisms provided by hardware.
|
* on the security mechanisms provided by hardware.
|
||||||
|
@ -657,4 +659,12 @@ struct drm_i915_gem_get_aperture {
|
||||||
__u64 aper_available_size;
|
__u64 aper_available_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct drm_i915_get_pipe_from_crtc_id {
|
||||||
|
/** ID of CRTC being requested **/
|
||||||
|
__u32 crtc_id;
|
||||||
|
|
||||||
|
/** pipe of requested CRTC **/
|
||||||
|
__u32 pipe;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* _I915_DRM_H_ */
|
#endif /* _I915_DRM_H_ */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче