diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_atomic_plane.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_atomic_plane.c | 48 |
1 files changed, 40 insertions, 8 deletions
diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c index 976b89156570..86ba4b2c3a65 100644 --- a/drivers/gpu/drm/i915/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c | |||
@@ -85,8 +85,8 @@ intel_plane_duplicate_state(struct drm_plane *plane) | |||
85 | return NULL; | 85 | return NULL; |
86 | 86 | ||
87 | state = &intel_state->base; | 87 | state = &intel_state->base; |
88 | if (state->fb) | 88 | |
89 | drm_framebuffer_reference(state->fb); | 89 | __drm_atomic_helper_plane_duplicate_state(plane, state); |
90 | 90 | ||
91 | return state; | 91 | return state; |
92 | } | 92 | } |
@@ -111,6 +111,7 @@ static int intel_plane_atomic_check(struct drm_plane *plane, | |||
111 | { | 111 | { |
112 | struct drm_crtc *crtc = state->crtc; | 112 | struct drm_crtc *crtc = state->crtc; |
113 | struct intel_crtc *intel_crtc; | 113 | struct intel_crtc *intel_crtc; |
114 | struct intel_crtc_state *crtc_state; | ||
114 | struct intel_plane *intel_plane = to_intel_plane(plane); | 115 | struct intel_plane *intel_plane = to_intel_plane(plane); |
115 | struct intel_plane_state *intel_state = to_intel_plane_state(state); | 116 | struct intel_plane_state *intel_state = to_intel_plane_state(state); |
116 | 117 | ||
@@ -126,6 +127,17 @@ static int intel_plane_atomic_check(struct drm_plane *plane, | |||
126 | if (!crtc) | 127 | if (!crtc) |
127 | return 0; | 128 | return 0; |
128 | 129 | ||
130 | /* FIXME: temporary hack necessary while we still use the plane update | ||
131 | * helper. */ | ||
132 | if (state->state) { | ||
133 | crtc_state = | ||
134 | intel_atomic_get_crtc_state(state->state, intel_crtc); | ||
135 | if (IS_ERR(crtc_state)) | ||
136 | return PTR_ERR(crtc_state); | ||
137 | } else { | ||
138 | crtc_state = intel_crtc->config; | ||
139 | } | ||
140 | |||
129 | /* | 141 | /* |
130 | * The original src/dest coordinates are stored in state->base, but | 142 | * The original src/dest coordinates are stored in state->base, but |
131 | * we want to keep another copy internal to our driver that we can | 143 | * we want to keep another copy internal to our driver that we can |
@@ -144,9 +156,9 @@ static int intel_plane_atomic_check(struct drm_plane *plane, | |||
144 | intel_state->clip.x1 = 0; | 156 | intel_state->clip.x1 = 0; |
145 | intel_state->clip.y1 = 0; | 157 | intel_state->clip.y1 = 0; |
146 | intel_state->clip.x2 = | 158 | intel_state->clip.x2 = |
147 | intel_crtc->active ? intel_crtc->config->pipe_src_w : 0; | 159 | crtc_state->base.active ? crtc_state->pipe_src_w : 0; |
148 | intel_state->clip.y2 = | 160 | intel_state->clip.y2 = |
149 | intel_crtc->active ? intel_crtc->config->pipe_src_h : 0; | 161 | crtc_state->base.active ? crtc_state->pipe_src_h : 0; |
150 | 162 | ||
151 | /* | 163 | /* |
152 | * Disabling a plane is always okay; we just need to update | 164 | * Disabling a plane is always okay; we just need to update |
@@ -162,6 +174,30 @@ static int intel_plane_atomic_check(struct drm_plane *plane, | |||
162 | (1 << drm_plane_index(plane)); | 174 | (1 << drm_plane_index(plane)); |
163 | } | 175 | } |
164 | 176 | ||
177 | if (state->fb && intel_rotation_90_or_270(state->rotation)) { | ||
178 | if (!(state->fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || | ||
179 | state->fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED)) { | ||
180 | DRM_DEBUG_KMS("Y/Yf tiling required for 90/270!\n"); | ||
181 | return -EINVAL; | ||
182 | } | ||
183 | |||
184 | /* | ||
185 | * 90/270 is not allowed with RGB64 16:16:16:16, | ||
186 | * RGB 16-bit 5:6:5, and Indexed 8-bit. | ||
187 | * TBD: Add RGB64 case once its added in supported format list. | ||
188 | */ | ||
189 | switch (state->fb->pixel_format) { | ||
190 | case DRM_FORMAT_C8: | ||
191 | case DRM_FORMAT_RGB565: | ||
192 | DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n", | ||
193 | drm_get_format_name(state->fb->pixel_format)); | ||
194 | return -EINVAL; | ||
195 | |||
196 | default: | ||
197 | break; | ||
198 | } | ||
199 | } | ||
200 | |||
165 | return intel_plane->check_plane(plane, intel_state); | 201 | return intel_plane->check_plane(plane, intel_state); |
166 | } | 202 | } |
167 | 203 | ||
@@ -172,10 +208,6 @@ static void intel_plane_atomic_update(struct drm_plane *plane, | |||
172 | struct intel_plane_state *intel_state = | 208 | struct intel_plane_state *intel_state = |
173 | to_intel_plane_state(plane->state); | 209 | to_intel_plane_state(plane->state); |
174 | 210 | ||
175 | /* Don't disable an already disabled plane */ | ||
176 | if (!plane->state->fb && !old_state->fb) | ||
177 | return; | ||
178 | |||
179 | intel_plane->commit_plane(plane, intel_state); | 211 | intel_plane->commit_plane(plane, intel_state); |
180 | } | 212 | } |
181 | 213 | ||