aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2018-09-27 19:37:51 -0400
committerDave Airlie <airlied@redhat.com>2018-09-27 19:37:55 -0400
commitdb9825c95498280718c4687fcf712016f5b6f5f6 (patch)
tree01661a811bcd16a7b6f3ee9790e77da75fd178b0 /drivers/gpu/drm/i915/intel_display.c
parent156e60bc71aa31a3b42b1d66a822c2999bd0994c (diff)
parent448626103dad54ec5d06722e955586b5d557625d (diff)
Merge tag 'drm-intel-next-2018-09-21' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
Driver Changes: - Bugzilla 107600: Fix stuttering video playback on MythTV on old hardware (Chris) - Avoid black screen when using CSC coefficient matrix (Raviraj) - Hammer PDs on Baytrail to make sure they reload (Chris) - Capture some objects if unable to capture all, on error (Chris) - Add W/A for 16 GB DIMMs on SKL+ (Mahesh) - Only enable IPC for symmetric memory configurations on KBL+ (Mahesh) - Assume pipe A to have maximum stride limits (Ville) - Always update update OA contexts via context image (Tvrtko) - Icelake enabling patches (Madhav, Dhinakaran) - Add Icelake DMC firmware (Anusha) - Fixes for CI found corner cases (Chris) - Limit the backpressure for request allocation (Chris) - Park GPU on module load so usage starts from known state (Chris) - Flush tasklet when checking for idle (Chris) - Use coherent write into the context image on BSW+ (Chris) - Fix possible integer overflow for framebuffers that get aligned past 4GiB (Ville) - Downgrade fence timeout from warn to notice and add debug hint (Chris) - Fixes to multi function encoder code (Ville) - Fix sprite plane check logic (Dan, Ville) - PAGE_SIZE vs. I915_GTT_PAGE_SIZE fixes (Ville) - Decode memory bandwidth and parameters for BXT and SKL+ (Mahesh) - Overwrite BIOS set IPC value from KMS (Mahesh) - Multiple pipe handling code cleanups/restructurings/optimizations (Ville) - Spare low 4G address for non-48bit objects (Chris) - Free context_setparam of struct_mutex (Chris) - Delay updating ring register state on resume (Chris) - Avoid unnecessarily copying overlay IOCTL parameters (Chris) - Update GuC power domain states even without submission (Michal) - Restore GuC preempt-context across S3/S4 (Chris) - Add kernel selftest for rapid context switching (Chris) - Keep runtime power management ref for live selftests (Chris) - GEM code cleanups (Matt) Signed-off-by: Dave Airlie <airlied@redhat.com> From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20180927095933.GA11458@jlahtine-desk.ger.corp.intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c632
1 files changed, 322 insertions, 310 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 5711cb701760..fbcc56caffb6 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1917,10 +1917,10 @@ static unsigned int intel_tile_size(const struct drm_i915_private *dev_priv)
1917} 1917}
1918 1918
1919static unsigned int 1919static unsigned int
1920intel_tile_width_bytes(const struct drm_framebuffer *fb, int plane) 1920intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane)
1921{ 1921{
1922 struct drm_i915_private *dev_priv = to_i915(fb->dev); 1922 struct drm_i915_private *dev_priv = to_i915(fb->dev);
1923 unsigned int cpp = fb->format->cpp[plane]; 1923 unsigned int cpp = fb->format->cpp[color_plane];
1924 1924
1925 switch (fb->modifier) { 1925 switch (fb->modifier) {
1926 case DRM_FORMAT_MOD_LINEAR: 1926 case DRM_FORMAT_MOD_LINEAR:
@@ -1931,7 +1931,7 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int plane)
1931 else 1931 else
1932 return 512; 1932 return 512;
1933 case I915_FORMAT_MOD_Y_TILED_CCS: 1933 case I915_FORMAT_MOD_Y_TILED_CCS:
1934 if (plane == 1) 1934 if (color_plane == 1)
1935 return 128; 1935 return 128;
1936 /* fall through */ 1936 /* fall through */
1937 case I915_FORMAT_MOD_Y_TILED: 1937 case I915_FORMAT_MOD_Y_TILED:
@@ -1940,7 +1940,7 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int plane)
1940 else 1940 else
1941 return 512; 1941 return 512;
1942 case I915_FORMAT_MOD_Yf_TILED_CCS: 1942 case I915_FORMAT_MOD_Yf_TILED_CCS:
1943 if (plane == 1) 1943 if (color_plane == 1)
1944 return 128; 1944 return 128;
1945 /* fall through */ 1945 /* fall through */
1946 case I915_FORMAT_MOD_Yf_TILED: 1946 case I915_FORMAT_MOD_Yf_TILED:
@@ -1965,22 +1965,22 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int plane)
1965} 1965}
1966 1966
1967static unsigned int 1967static unsigned int
1968intel_tile_height(const struct drm_framebuffer *fb, int plane) 1968intel_tile_height(const struct drm_framebuffer *fb, int color_plane)
1969{ 1969{
1970 if (fb->modifier == DRM_FORMAT_MOD_LINEAR) 1970 if (fb->modifier == DRM_FORMAT_MOD_LINEAR)
1971 return 1; 1971 return 1;
1972 else 1972 else
1973 return intel_tile_size(to_i915(fb->dev)) / 1973 return intel_tile_size(to_i915(fb->dev)) /
1974 intel_tile_width_bytes(fb, plane); 1974 intel_tile_width_bytes(fb, color_plane);
1975} 1975}
1976 1976
1977/* Return the tile dimensions in pixel units */ 1977/* Return the tile dimensions in pixel units */
1978static void intel_tile_dims(const struct drm_framebuffer *fb, int plane, 1978static void intel_tile_dims(const struct drm_framebuffer *fb, int color_plane,
1979 unsigned int *tile_width, 1979 unsigned int *tile_width,
1980 unsigned int *tile_height) 1980 unsigned int *tile_height)
1981{ 1981{
1982 unsigned int tile_width_bytes = intel_tile_width_bytes(fb, plane); 1982 unsigned int tile_width_bytes = intel_tile_width_bytes(fb, color_plane);
1983 unsigned int cpp = fb->format->cpp[plane]; 1983 unsigned int cpp = fb->format->cpp[color_plane];
1984 1984
1985 *tile_width = tile_width_bytes / cpp; 1985 *tile_width = tile_width_bytes / cpp;
1986 *tile_height = intel_tile_size(to_i915(fb->dev)) / tile_width_bytes; 1986 *tile_height = intel_tile_size(to_i915(fb->dev)) / tile_width_bytes;
@@ -1988,9 +1988,9 @@ static void intel_tile_dims(const struct drm_framebuffer *fb, int plane,
1988 1988
1989unsigned int 1989unsigned int
1990intel_fb_align_height(const struct drm_framebuffer *fb, 1990intel_fb_align_height(const struct drm_framebuffer *fb,
1991 int plane, unsigned int height) 1991 int color_plane, unsigned int height)
1992{ 1992{
1993 unsigned int tile_height = intel_tile_height(fb, plane); 1993 unsigned int tile_height = intel_tile_height(fb, color_plane);
1994 1994
1995 return ALIGN(height, tile_height); 1995 return ALIGN(height, tile_height);
1996} 1996}
@@ -2044,12 +2044,12 @@ static unsigned int intel_linear_alignment(const struct drm_i915_private *dev_pr
2044} 2044}
2045 2045
2046static unsigned int intel_surf_alignment(const struct drm_framebuffer *fb, 2046static unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
2047 int plane) 2047 int color_plane)
2048{ 2048{
2049 struct drm_i915_private *dev_priv = to_i915(fb->dev); 2049 struct drm_i915_private *dev_priv = to_i915(fb->dev);
2050 2050
2051 /* AUX_DIST needs only 4K alignment */ 2051 /* AUX_DIST needs only 4K alignment */
2052 if (plane == 1) 2052 if (color_plane == 1)
2053 return 4096; 2053 return 4096;
2054 2054
2055 switch (fb->modifier) { 2055 switch (fb->modifier) {
@@ -2080,14 +2080,13 @@ static bool intel_plane_uses_fence(const struct intel_plane_state *plane_state)
2080 2080
2081struct i915_vma * 2081struct i915_vma *
2082intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, 2082intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
2083 unsigned int rotation, 2083 const struct i915_ggtt_view *view,
2084 bool uses_fence, 2084 bool uses_fence,
2085 unsigned long *out_flags) 2085 unsigned long *out_flags)
2086{ 2086{
2087 struct drm_device *dev = fb->dev; 2087 struct drm_device *dev = fb->dev;
2088 struct drm_i915_private *dev_priv = to_i915(dev); 2088 struct drm_i915_private *dev_priv = to_i915(dev);
2089 struct drm_i915_gem_object *obj = intel_fb_obj(fb); 2089 struct drm_i915_gem_object *obj = intel_fb_obj(fb);
2090 struct i915_ggtt_view view;
2091 struct i915_vma *vma; 2090 struct i915_vma *vma;
2092 unsigned int pinctl; 2091 unsigned int pinctl;
2093 u32 alignment; 2092 u32 alignment;
@@ -2096,8 +2095,6 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
2096 2095
2097 alignment = intel_surf_alignment(fb, 0); 2096 alignment = intel_surf_alignment(fb, 0);
2098 2097
2099 intel_fill_fb_ggtt_view(&view, fb, rotation);
2100
2101 /* Note that the w/a also requires 64 PTE of padding following the 2098 /* Note that the w/a also requires 64 PTE of padding following the
2102 * bo. We currently fill all unused PTE with the shadow page and so 2099 * bo. We currently fill all unused PTE with the shadow page and so
2103 * we should always have valid PTE following the scanout preventing 2100 * we should always have valid PTE following the scanout preventing
@@ -2130,7 +2127,7 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
2130 pinctl |= PIN_MAPPABLE; 2127 pinctl |= PIN_MAPPABLE;
2131 2128
2132 vma = i915_gem_object_pin_to_display_plane(obj, 2129 vma = i915_gem_object_pin_to_display_plane(obj,
2133 alignment, &view, pinctl); 2130 alignment, view, pinctl);
2134 if (IS_ERR(vma)) 2131 if (IS_ERR(vma))
2135 goto err; 2132 goto err;
2136 2133
@@ -2182,13 +2179,13 @@ void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags)
2182 i915_vma_put(vma); 2179 i915_vma_put(vma);
2183} 2180}
2184 2181
2185static int intel_fb_pitch(const struct drm_framebuffer *fb, int plane, 2182static int intel_fb_pitch(const struct drm_framebuffer *fb, int color_plane,
2186 unsigned int rotation) 2183 unsigned int rotation)
2187{ 2184{
2188 if (drm_rotation_90_or_270(rotation)) 2185 if (drm_rotation_90_or_270(rotation))
2189 return to_intel_framebuffer(fb)->rotated[plane].pitch; 2186 return to_intel_framebuffer(fb)->rotated[color_plane].pitch;
2190 else 2187 else
2191 return fb->pitches[plane]; 2188 return fb->pitches[color_plane];
2192} 2189}
2193 2190
2194/* 2191/*
@@ -2199,11 +2196,11 @@ static int intel_fb_pitch(const struct drm_framebuffer *fb, int plane,
2199 */ 2196 */
2200u32 intel_fb_xy_to_linear(int x, int y, 2197u32 intel_fb_xy_to_linear(int x, int y,
2201 const struct intel_plane_state *state, 2198 const struct intel_plane_state *state,
2202 int plane) 2199 int color_plane)
2203{ 2200{
2204 const struct drm_framebuffer *fb = state->base.fb; 2201 const struct drm_framebuffer *fb = state->base.fb;
2205 unsigned int cpp = fb->format->cpp[plane]; 2202 unsigned int cpp = fb->format->cpp[color_plane];
2206 unsigned int pitch = fb->pitches[plane]; 2203 unsigned int pitch = state->color_plane[color_plane].stride;
2207 2204
2208 return y * pitch + x * cpp; 2205 return y * pitch + x * cpp;
2209} 2206}
@@ -2215,28 +2212,28 @@ u32 intel_fb_xy_to_linear(int x, int y,
2215 */ 2212 */
2216void intel_add_fb_offsets(int *x, int *y, 2213void intel_add_fb_offsets(int *x, int *y,
2217 const struct intel_plane_state *state, 2214 const struct intel_plane_state *state,
2218 int plane) 2215 int color_plane)
2219 2216
2220{ 2217{
2221 const struct intel_framebuffer *intel_fb = to_intel_framebuffer(state->base.fb); 2218 const struct intel_framebuffer *intel_fb = to_intel_framebuffer(state->base.fb);
2222 unsigned int rotation = state->base.rotation; 2219 unsigned int rotation = state->base.rotation;
2223 2220
2224 if (drm_rotation_90_or_270(rotation)) { 2221 if (drm_rotation_90_or_270(rotation)) {
2225 *x += intel_fb->rotated[plane].x; 2222 *x += intel_fb->rotated[color_plane].x;
2226 *y += intel_fb->rotated[plane].y; 2223 *y += intel_fb->rotated[color_plane].y;
2227 } else { 2224 } else {
2228 *x += intel_fb->normal[plane].x; 2225 *x += intel_fb->normal[color_plane].x;
2229 *y += intel_fb->normal[plane].y; 2226 *y += intel_fb->normal[color_plane].y;
2230 } 2227 }
2231} 2228}
2232 2229
2233static u32 __intel_adjust_tile_offset(int *x, int *y, 2230static u32 intel_adjust_tile_offset(int *x, int *y,
2234 unsigned int tile_width, 2231 unsigned int tile_width,
2235 unsigned int tile_height, 2232 unsigned int tile_height,
2236 unsigned int tile_size, 2233 unsigned int tile_size,
2237 unsigned int pitch_tiles, 2234 unsigned int pitch_tiles,
2238 u32 old_offset, 2235 u32 old_offset,
2239 u32 new_offset) 2236 u32 new_offset)
2240{ 2237{
2241 unsigned int pitch_pixels = pitch_tiles * tile_width; 2238 unsigned int pitch_pixels = pitch_tiles * tile_width;
2242 unsigned int tiles; 2239 unsigned int tiles;
@@ -2257,14 +2254,15 @@ static u32 __intel_adjust_tile_offset(int *x, int *y,
2257 return new_offset; 2254 return new_offset;
2258} 2255}
2259 2256
2260static u32 _intel_adjust_tile_offset(int *x, int *y, 2257static u32 intel_adjust_aligned_offset(int *x, int *y,
2261 const struct drm_framebuffer *fb, int plane, 2258 const struct drm_framebuffer *fb,
2262 unsigned int rotation, 2259 int color_plane,
2263 u32 old_offset, u32 new_offset) 2260 unsigned int rotation,
2261 unsigned int pitch,
2262 u32 old_offset, u32 new_offset)
2264{ 2263{
2265 const struct drm_i915_private *dev_priv = to_i915(fb->dev); 2264 struct drm_i915_private *dev_priv = to_i915(fb->dev);
2266 unsigned int cpp = fb->format->cpp[plane]; 2265 unsigned int cpp = fb->format->cpp[color_plane];
2267 unsigned int pitch = intel_fb_pitch(fb, plane, rotation);
2268 2266
2269 WARN_ON(new_offset > old_offset); 2267 WARN_ON(new_offset > old_offset);
2270 2268
@@ -2273,7 +2271,7 @@ static u32 _intel_adjust_tile_offset(int *x, int *y,
2273 unsigned int pitch_tiles; 2271 unsigned int pitch_tiles;
2274 2272
2275 tile_size = intel_tile_size(dev_priv); 2273 tile_size = intel_tile_size(dev_priv);
2276 intel_tile_dims(fb, plane, &tile_width, &tile_height); 2274 intel_tile_dims(fb, color_plane, &tile_width, &tile_height);
2277 2275
2278 if (drm_rotation_90_or_270(rotation)) { 2276 if (drm_rotation_90_or_270(rotation)) {
2279 pitch_tiles = pitch / tile_height; 2277 pitch_tiles = pitch / tile_height;
@@ -2282,9 +2280,9 @@ static u32 _intel_adjust_tile_offset(int *x, int *y,
2282 pitch_tiles = pitch / (tile_width * cpp); 2280 pitch_tiles = pitch / (tile_width * cpp);
2283 } 2281 }
2284 2282
2285 __intel_adjust_tile_offset(x, y, tile_width, tile_height, 2283 intel_adjust_tile_offset(x, y, tile_width, tile_height,
2286 tile_size, pitch_tiles, 2284 tile_size, pitch_tiles,
2287 old_offset, new_offset); 2285 old_offset, new_offset);
2288 } else { 2286 } else {
2289 old_offset += *y * pitch + *x * cpp; 2287 old_offset += *y * pitch + *x * cpp;
2290 2288
@@ -2299,17 +2297,19 @@ static u32 _intel_adjust_tile_offset(int *x, int *y,
2299 * Adjust the tile offset by moving the difference into 2297 * Adjust the tile offset by moving the difference into
2300 * the x/y offsets. 2298 * the x/y offsets.
2301 */ 2299 */
2302static u32 intel_adjust_tile_offset(int *x, int *y, 2300static u32 intel_plane_adjust_aligned_offset(int *x, int *y,
2303 const struct intel_plane_state *state, int plane, 2301 const struct intel_plane_state *state,
2304 u32 old_offset, u32 new_offset) 2302 int color_plane,
2305{ 2303 u32 old_offset, u32 new_offset)
2306 return _intel_adjust_tile_offset(x, y, state->base.fb, plane, 2304{
2307 state->base.rotation, 2305 return intel_adjust_aligned_offset(x, y, state->base.fb, color_plane,
2308 old_offset, new_offset); 2306 state->base.rotation,
2307 state->color_plane[color_plane].stride,
2308 old_offset, new_offset);
2309} 2309}
2310 2310
2311/* 2311/*
2312 * Computes the linear offset to the base tile and adjusts 2312 * Computes the aligned offset to the base tile and adjusts
2313 * x, y. bytes per pixel is assumed to be a power-of-two. 2313 * x, y. bytes per pixel is assumed to be a power-of-two.
2314 * 2314 *
2315 * In the 90/270 rotated case, x and y are assumed 2315 * In the 90/270 rotated case, x and y are assumed
@@ -2322,15 +2322,16 @@ static u32 intel_adjust_tile_offset(int *x, int *y,
2322 * used. This is why the user has to pass in the pitch since it 2322 * used. This is why the user has to pass in the pitch since it
2323 * is specified in the rotated orientation. 2323 * is specified in the rotated orientation.
2324 */ 2324 */
2325static u32 _intel_compute_tile_offset(const struct drm_i915_private *dev_priv, 2325static u32 intel_compute_aligned_offset(struct drm_i915_private *dev_priv,
2326 int *x, int *y, 2326 int *x, int *y,
2327 const struct drm_framebuffer *fb, int plane, 2327 const struct drm_framebuffer *fb,
2328 unsigned int pitch, 2328 int color_plane,
2329 unsigned int rotation, 2329 unsigned int pitch,
2330 u32 alignment) 2330 unsigned int rotation,
2331 u32 alignment)
2331{ 2332{
2332 uint64_t fb_modifier = fb->modifier; 2333 uint64_t fb_modifier = fb->modifier;
2333 unsigned int cpp = fb->format->cpp[plane]; 2334 unsigned int cpp = fb->format->cpp[color_plane];
2334 u32 offset, offset_aligned; 2335 u32 offset, offset_aligned;
2335 2336
2336 if (alignment) 2337 if (alignment)
@@ -2341,7 +2342,7 @@ static u32 _intel_compute_tile_offset(const struct drm_i915_private *dev_priv,
2341 unsigned int tile_rows, tiles, pitch_tiles; 2342 unsigned int tile_rows, tiles, pitch_tiles;
2342 2343
2343 tile_size = intel_tile_size(dev_priv); 2344 tile_size = intel_tile_size(dev_priv);
2344 intel_tile_dims(fb, plane, &tile_width, &tile_height); 2345 intel_tile_dims(fb, color_plane, &tile_width, &tile_height);
2345 2346
2346 if (drm_rotation_90_or_270(rotation)) { 2347 if (drm_rotation_90_or_270(rotation)) {
2347 pitch_tiles = pitch / tile_height; 2348 pitch_tiles = pitch / tile_height;
@@ -2359,9 +2360,9 @@ static u32 _intel_compute_tile_offset(const struct drm_i915_private *dev_priv,
2359 offset = (tile_rows * pitch_tiles + tiles) * tile_size; 2360 offset = (tile_rows * pitch_tiles + tiles) * tile_size;
2360 offset_aligned = offset & ~alignment; 2361 offset_aligned = offset & ~alignment;
2361 2362
2362 __intel_adjust_tile_offset(x, y, tile_width, tile_height, 2363 intel_adjust_tile_offset(x, y, tile_width, tile_height,
2363 tile_size, pitch_tiles, 2364 tile_size, pitch_tiles,
2364 offset, offset_aligned); 2365 offset, offset_aligned);
2365 } else { 2366 } else {
2366 offset = *y * pitch + *x * cpp; 2367 offset = *y * pitch + *x * cpp;
2367 offset_aligned = offset & ~alignment; 2368 offset_aligned = offset & ~alignment;
@@ -2373,42 +2374,44 @@ static u32 _intel_compute_tile_offset(const struct drm_i915_private *dev_priv,
2373 return offset_aligned; 2374 return offset_aligned;
2374} 2375}
2375 2376
2376u32 intel_compute_tile_offset(int *x, int *y, 2377static u32 intel_plane_compute_aligned_offset(int *x, int *y,
2377 const struct intel_plane_state *state, 2378 const struct intel_plane_state *state,
2378 int plane) 2379 int color_plane)
2379{ 2380{
2380 struct intel_plane *intel_plane = to_intel_plane(state->base.plane); 2381 struct intel_plane *intel_plane = to_intel_plane(state->base.plane);
2381 struct drm_i915_private *dev_priv = to_i915(intel_plane->base.dev); 2382 struct drm_i915_private *dev_priv = to_i915(intel_plane->base.dev);
2382 const struct drm_framebuffer *fb = state->base.fb; 2383 const struct drm_framebuffer *fb = state->base.fb;
2383 unsigned int rotation = state->base.rotation; 2384 unsigned int rotation = state->base.rotation;
2384 int pitch = intel_fb_pitch(fb, plane, rotation); 2385 int pitch = state->color_plane[color_plane].stride;
2385 u32 alignment; 2386 u32 alignment;
2386 2387
2387 if (intel_plane->id == PLANE_CURSOR) 2388 if (intel_plane->id == PLANE_CURSOR)
2388 alignment = intel_cursor_alignment(dev_priv); 2389 alignment = intel_cursor_alignment(dev_priv);
2389 else 2390 else
2390 alignment = intel_surf_alignment(fb, plane); 2391 alignment = intel_surf_alignment(fb, color_plane);
2391 2392
2392 return _intel_compute_tile_offset(dev_priv, x, y, fb, plane, pitch, 2393 return intel_compute_aligned_offset(dev_priv, x, y, fb, color_plane,
2393 rotation, alignment); 2394 pitch, rotation, alignment);
2394} 2395}
2395 2396
2396/* Convert the fb->offset[] into x/y offsets */ 2397/* Convert the fb->offset[] into x/y offsets */
2397static int intel_fb_offset_to_xy(int *x, int *y, 2398static int intel_fb_offset_to_xy(int *x, int *y,
2398 const struct drm_framebuffer *fb, int plane) 2399 const struct drm_framebuffer *fb,
2400 int color_plane)
2399{ 2401{
2400 struct drm_i915_private *dev_priv = to_i915(fb->dev); 2402 struct drm_i915_private *dev_priv = to_i915(fb->dev);
2401 2403
2402 if (fb->modifier != DRM_FORMAT_MOD_LINEAR && 2404 if (fb->modifier != DRM_FORMAT_MOD_LINEAR &&
2403 fb->offsets[plane] % intel_tile_size(dev_priv)) 2405 fb->offsets[color_plane] % intel_tile_size(dev_priv))
2404 return -EINVAL; 2406 return -EINVAL;
2405 2407
2406 *x = 0; 2408 *x = 0;
2407 *y = 0; 2409 *y = 0;
2408 2410
2409 _intel_adjust_tile_offset(x, y, 2411 intel_adjust_aligned_offset(x, y,
2410 fb, plane, DRM_MODE_ROTATE_0, 2412 fb, color_plane, DRM_MODE_ROTATE_0,
2411 fb->offsets[plane], 0); 2413 fb->pitches[color_plane],
2414 fb->offsets[color_plane], 0);
2412 2415
2413 return 0; 2416 return 0;
2414} 2417}
@@ -2565,9 +2568,10 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv,
2565 intel_fb->normal[i].x = x; 2568 intel_fb->normal[i].x = x;
2566 intel_fb->normal[i].y = y; 2569 intel_fb->normal[i].y = y;
2567 2570
2568 offset = _intel_compute_tile_offset(dev_priv, &x, &y, 2571 offset = intel_compute_aligned_offset(dev_priv, &x, &y, fb, i,
2569 fb, i, fb->pitches[i], 2572 fb->pitches[i],
2570 DRM_MODE_ROTATE_0, tile_size); 2573 DRM_MODE_ROTATE_0,
2574 tile_size);
2571 offset /= tile_size; 2575 offset /= tile_size;
2572 2576
2573 if (fb->modifier != DRM_FORMAT_MOD_LINEAR) { 2577 if (fb->modifier != DRM_FORMAT_MOD_LINEAR) {
@@ -2614,10 +2618,10 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv,
2614 * We only keep the x/y offsets, so push all of the 2618 * We only keep the x/y offsets, so push all of the
2615 * gtt offset into the x/y offsets. 2619 * gtt offset into the x/y offsets.
2616 */ 2620 */
2617 __intel_adjust_tile_offset(&x, &y, 2621 intel_adjust_tile_offset(&x, &y,
2618 tile_width, tile_height, 2622 tile_width, tile_height,
2619 tile_size, pitch_tiles, 2623 tile_size, pitch_tiles,
2620 gtt_offset_rotated * tile_size, 0); 2624 gtt_offset_rotated * tile_size, 0);
2621 2625
2622 gtt_offset_rotated += rot_info->plane[i].width * rot_info->plane[i].height; 2626 gtt_offset_rotated += rot_info->plane[i].width * rot_info->plane[i].height;
2623 2627
@@ -2636,9 +2640,9 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv,
2636 max_size = max(max_size, offset + size); 2640 max_size = max(max_size, offset + size);
2637 } 2641 }
2638 2642
2639 if (max_size * tile_size > obj->base.size) { 2643 if (mul_u32_u32(max_size, tile_size) > obj->base.size) {
2640 DRM_DEBUG_KMS("fb too big for bo (need %u bytes, have %zu bytes)\n", 2644 DRM_DEBUG_KMS("fb too big for bo (need %llu bytes, have %zu bytes)\n",
2641 max_size * tile_size, obj->base.size); 2645 mul_u32_u32(max_size, tile_size), obj->base.size);
2642 return -EINVAL; 2646 return -EINVAL;
2643 } 2647 }
2644 2648
@@ -2853,10 +2857,15 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
2853 return; 2857 return;
2854 2858
2855valid_fb: 2859valid_fb:
2860 intel_fill_fb_ggtt_view(&intel_state->view, fb,
2861 intel_state->base.rotation);
2862 intel_state->color_plane[0].stride =
2863 intel_fb_pitch(fb, 0, intel_state->base.rotation);
2864
2856 mutex_lock(&dev->struct_mutex); 2865 mutex_lock(&dev->struct_mutex);
2857 intel_state->vma = 2866 intel_state->vma =
2858 intel_pin_and_fence_fb_obj(fb, 2867 intel_pin_and_fence_fb_obj(fb,
2859 primary->state->rotation, 2868 &intel_state->view,
2860 intel_plane_uses_fence(intel_state), 2869 intel_plane_uses_fence(intel_state),
2861 &intel_state->flags); 2870 &intel_state->flags);
2862 mutex_unlock(&dev->struct_mutex); 2871 mutex_unlock(&dev->struct_mutex);
@@ -2899,10 +2908,11 @@ valid_fb:
2899 &obj->frontbuffer_bits); 2908 &obj->frontbuffer_bits);
2900} 2909}
2901 2910
2902static int skl_max_plane_width(const struct drm_framebuffer *fb, int plane, 2911static int skl_max_plane_width(const struct drm_framebuffer *fb,
2912 int color_plane,
2903 unsigned int rotation) 2913 unsigned int rotation)
2904{ 2914{
2905 int cpp = fb->format->cpp[plane]; 2915 int cpp = fb->format->cpp[color_plane];
2906 2916
2907 switch (fb->modifier) { 2917 switch (fb->modifier) {
2908 case DRM_FORMAT_MOD_LINEAR: 2918 case DRM_FORMAT_MOD_LINEAR:
@@ -2950,9 +2960,9 @@ static bool skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state
2950 const struct drm_framebuffer *fb = plane_state->base.fb; 2960 const struct drm_framebuffer *fb = plane_state->base.fb;
2951 int hsub = fb->format->hsub; 2961 int hsub = fb->format->hsub;
2952 int vsub = fb->format->vsub; 2962 int vsub = fb->format->vsub;
2953 int aux_x = plane_state->aux.x; 2963 int aux_x = plane_state->color_plane[1].x;
2954 int aux_y = plane_state->aux.y; 2964 int aux_y = plane_state->color_plane[1].y;
2955 u32 aux_offset = plane_state->aux.offset; 2965 u32 aux_offset = plane_state->color_plane[1].offset;
2956 u32 alignment = intel_surf_alignment(fb, 1); 2966 u32 alignment = intel_surf_alignment(fb, 1);
2957 2967
2958 while (aux_offset >= main_offset && aux_y <= main_y) { 2968 while (aux_offset >= main_offset && aux_y <= main_y) {
@@ -2966,8 +2976,8 @@ static bool skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state
2966 2976
2967 x = aux_x / hsub; 2977 x = aux_x / hsub;
2968 y = aux_y / vsub; 2978 y = aux_y / vsub;
2969 aux_offset = intel_adjust_tile_offset(&x, &y, plane_state, 1, 2979 aux_offset = intel_plane_adjust_aligned_offset(&x, &y, plane_state, 1,
2970 aux_offset, aux_offset - alignment); 2980 aux_offset, aux_offset - alignment);
2971 aux_x = x * hsub + aux_x % hsub; 2981 aux_x = x * hsub + aux_x % hsub;
2972 aux_y = y * vsub + aux_y % vsub; 2982 aux_y = y * vsub + aux_y % vsub;
2973 } 2983 }
@@ -2975,30 +2985,24 @@ static bool skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state
2975 if (aux_x != main_x || aux_y != main_y) 2985 if (aux_x != main_x || aux_y != main_y)
2976 return false; 2986 return false;
2977 2987
2978 plane_state->aux.offset = aux_offset; 2988 plane_state->color_plane[1].offset = aux_offset;
2979 plane_state->aux.x = aux_x; 2989 plane_state->color_plane[1].x = aux_x;
2980 plane_state->aux.y = aux_y; 2990 plane_state->color_plane[1].y = aux_y;
2981 2991
2982 return true; 2992 return true;
2983} 2993}
2984 2994
2985static int skl_check_main_surface(const struct intel_crtc_state *crtc_state, 2995static int skl_check_main_surface(struct intel_plane_state *plane_state)
2986 struct intel_plane_state *plane_state)
2987{ 2996{
2988 struct drm_i915_private *dev_priv =
2989 to_i915(plane_state->base.plane->dev);
2990 const struct drm_framebuffer *fb = plane_state->base.fb; 2997 const struct drm_framebuffer *fb = plane_state->base.fb;
2991 unsigned int rotation = plane_state->base.rotation; 2998 unsigned int rotation = plane_state->base.rotation;
2992 int x = plane_state->base.src.x1 >> 16; 2999 int x = plane_state->base.src.x1 >> 16;
2993 int y = plane_state->base.src.y1 >> 16; 3000 int y = plane_state->base.src.y1 >> 16;
2994 int w = drm_rect_width(&plane_state->base.src) >> 16; 3001 int w = drm_rect_width(&plane_state->base.src) >> 16;
2995 int h = drm_rect_height(&plane_state->base.src) >> 16; 3002 int h = drm_rect_height(&plane_state->base.src) >> 16;
2996 int dst_x = plane_state->base.dst.x1;
2997 int dst_w = drm_rect_width(&plane_state->base.dst);
2998 int pipe_src_w = crtc_state->pipe_src_w;
2999 int max_width = skl_max_plane_width(fb, 0, rotation); 3003 int max_width = skl_max_plane_width(fb, 0, rotation);
3000 int max_height = 4096; 3004 int max_height = 4096;
3001 u32 alignment, offset, aux_offset = plane_state->aux.offset; 3005 u32 alignment, offset, aux_offset = plane_state->color_plane[1].offset;
3002 3006
3003 if (w > max_width || h > max_height) { 3007 if (w > max_width || h > max_height) {
3004 DRM_DEBUG_KMS("requested Y/RGB source size %dx%d too big (limit %dx%d)\n", 3008 DRM_DEBUG_KMS("requested Y/RGB source size %dx%d too big (limit %dx%d)\n",
@@ -3006,26 +3010,8 @@ static int skl_check_main_surface(const struct intel_crtc_state *crtc_state,
3006 return -EINVAL; 3010 return -EINVAL;
3007 } 3011 }
3008 3012
3009 /*
3010 * Display WA #1175: cnl,glk
3011 * Planes other than the cursor may cause FIFO underflow and display
3012 * corruption if starting less than 4 pixels from the right edge of
3013 * the screen.
3014 * Besides the above WA fix the similar problem, where planes other
3015 * than the cursor ending less than 4 pixels from the left edge of the
3016 * screen may cause FIFO underflow and display corruption.
3017 */
3018 if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
3019 (dst_x + dst_w < 4 || dst_x > pipe_src_w - 4)) {
3020 DRM_DEBUG_KMS("requested plane X %s position %d invalid (valid range %d-%d)\n",
3021 dst_x + dst_w < 4 ? "end" : "start",
3022 dst_x + dst_w < 4 ? dst_x + dst_w : dst_x,
3023 4, pipe_src_w - 4);
3024 return -ERANGE;
3025 }
3026
3027 intel_add_fb_offsets(&x, &y, plane_state, 0); 3013 intel_add_fb_offsets(&x, &y, plane_state, 0);
3028 offset = intel_compute_tile_offset(&x, &y, plane_state, 0); 3014 offset = intel_plane_compute_aligned_offset(&x, &y, plane_state, 0);
3029 alignment = intel_surf_alignment(fb, 0); 3015 alignment = intel_surf_alignment(fb, 0);
3030 3016
3031 /* 3017 /*
@@ -3034,8 +3020,8 @@ static int skl_check_main_surface(const struct intel_crtc_state *crtc_state,
3034 * sure that is what we will get. 3020 * sure that is what we will get.
3035 */ 3021 */
3036 if (offset > aux_offset) 3022 if (offset > aux_offset)
3037 offset = intel_adjust_tile_offset(&x, &y, plane_state, 0, 3023 offset = intel_plane_adjust_aligned_offset(&x, &y, plane_state, 0,
3038 offset, aux_offset & ~(alignment - 1)); 3024 offset, aux_offset & ~(alignment - 1));
3039 3025
3040 /* 3026 /*
3041 * When using an X-tiled surface, the plane blows up 3027 * When using an X-tiled surface, the plane blows up
@@ -3046,14 +3032,14 @@ static int skl_check_main_surface(const struct intel_crtc_state *crtc_state,
3046 if (fb->modifier == I915_FORMAT_MOD_X_TILED) { 3032 if (fb->modifier == I915_FORMAT_MOD_X_TILED) {
3047 int cpp = fb->format->cpp[0]; 3033 int cpp = fb->format->cpp[0];
3048 3034
3049 while ((x + w) * cpp > fb->pitches[0]) { 3035 while ((x + w) * cpp > plane_state->color_plane[0].stride) {
3050 if (offset == 0) { 3036 if (offset == 0) {
3051 DRM_DEBUG_KMS("Unable to find suitable display surface offset due to X-tiling\n"); 3037 DRM_DEBUG_KMS("Unable to find suitable display surface offset due to X-tiling\n");
3052 return -EINVAL; 3038 return -EINVAL;
3053 } 3039 }
3054 3040
3055 offset = intel_adjust_tile_offset(&x, &y, plane_state, 0, 3041 offset = intel_plane_adjust_aligned_offset(&x, &y, plane_state, 0,
3056 offset, offset - alignment); 3042 offset, offset - alignment);
3057 } 3043 }
3058 } 3044 }
3059 3045
@@ -3066,26 +3052,25 @@ static int skl_check_main_surface(const struct intel_crtc_state *crtc_state,
3066 if (offset == 0) 3052 if (offset == 0)
3067 break; 3053 break;
3068 3054
3069 offset = intel_adjust_tile_offset(&x, &y, plane_state, 0, 3055 offset = intel_plane_adjust_aligned_offset(&x, &y, plane_state, 0,
3070 offset, offset - alignment); 3056 offset, offset - alignment);
3071 } 3057 }
3072 3058
3073 if (x != plane_state->aux.x || y != plane_state->aux.y) { 3059 if (x != plane_state->color_plane[1].x || y != plane_state->color_plane[1].y) {
3074 DRM_DEBUG_KMS("Unable to find suitable display surface offset due to CCS\n"); 3060 DRM_DEBUG_KMS("Unable to find suitable display surface offset due to CCS\n");
3075 return -EINVAL; 3061 return -EINVAL;
3076 } 3062 }
3077 } 3063 }
3078 3064
3079 plane_state->main.offset = offset; 3065 plane_state->color_plane[0].offset = offset;
3080 plane_state->main.x = x; 3066 plane_state->color_plane[0].x = x;
3081 plane_state->main.y = y; 3067 plane_state->color_plane[0].y = y;
3082 3068
3083 return 0; 3069 return 0;
3084} 3070}
3085 3071
3086static int 3072static int
3087skl_check_nv12_surface(const struct intel_crtc_state *crtc_state, 3073skl_check_nv12_surface(struct intel_plane_state *plane_state)
3088 struct intel_plane_state *plane_state)
3089{ 3074{
3090 /* Display WA #1106 */ 3075 /* Display WA #1106 */
3091 if (plane_state->base.rotation != 3076 if (plane_state->base.rotation !=
@@ -3119,7 +3104,7 @@ static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
3119 u32 offset; 3104 u32 offset;
3120 3105
3121 intel_add_fb_offsets(&x, &y, plane_state, 1); 3106 intel_add_fb_offsets(&x, &y, plane_state, 1);
3122 offset = intel_compute_tile_offset(&x, &y, plane_state, 1); 3107 offset = intel_plane_compute_aligned_offset(&x, &y, plane_state, 1);
3123 3108
3124 /* FIXME not quite sure how/if these apply to the chroma plane */ 3109 /* FIXME not quite sure how/if these apply to the chroma plane */
3125 if (w > max_width || h > max_height) { 3110 if (w > max_width || h > max_height) {
@@ -3128,9 +3113,9 @@ static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
3128 return -EINVAL; 3113 return -EINVAL;
3129 } 3114 }
3130 3115
3131 plane_state->aux.offset = offset; 3116 plane_state->color_plane[1].offset = offset;
3132 plane_state->aux.x = x; 3117 plane_state->color_plane[1].x = x;
3133 plane_state->aux.y = y; 3118 plane_state->color_plane[1].y = y;
3134 3119
3135 return 0; 3120 return 0;
3136} 3121}
@@ -3146,34 +3131,25 @@ static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state)
3146 int y = src_y / vsub; 3131 int y = src_y / vsub;
3147 u32 offset; 3132 u32 offset;
3148 3133
3149 if (plane_state->base.rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180)) {
3150 DRM_DEBUG_KMS("RC support only with 0/180 degree rotation %x\n",
3151 plane_state->base.rotation);
3152 return -EINVAL;
3153 }
3154
3155 intel_add_fb_offsets(&x, &y, plane_state, 1); 3134 intel_add_fb_offsets(&x, &y, plane_state, 1);
3156 offset = intel_compute_tile_offset(&x, &y, plane_state, 1); 3135 offset = intel_plane_compute_aligned_offset(&x, &y, plane_state, 1);
3157 3136
3158 plane_state->aux.offset = offset; 3137 plane_state->color_plane[1].offset = offset;
3159 plane_state->aux.x = x * hsub + src_x % hsub; 3138 plane_state->color_plane[1].x = x * hsub + src_x % hsub;
3160 plane_state->aux.y = y * vsub + src_y % vsub; 3139 plane_state->color_plane[1].y = y * vsub + src_y % vsub;
3161 3140
3162 return 0; 3141 return 0;
3163} 3142}
3164 3143
3165int skl_check_plane_surface(const struct intel_crtc_state *crtc_state, 3144int skl_check_plane_surface(struct intel_plane_state *plane_state)
3166 struct intel_plane_state *plane_state)
3167{ 3145{
3168 const struct drm_framebuffer *fb = plane_state->base.fb; 3146 const struct drm_framebuffer *fb = plane_state->base.fb;
3169 unsigned int rotation = plane_state->base.rotation; 3147 unsigned int rotation = plane_state->base.rotation;
3170 int ret; 3148 int ret;
3171 3149
3172 if (rotation & DRM_MODE_REFLECT_X && 3150 intel_fill_fb_ggtt_view(&plane_state->view, fb, rotation);
3173 fb->modifier == DRM_FORMAT_MOD_LINEAR) { 3151 plane_state->color_plane[0].stride = intel_fb_pitch(fb, 0, rotation);
3174 DRM_DEBUG_KMS("horizontal flip is not supported with linear surface formats\n"); 3152 plane_state->color_plane[1].stride = intel_fb_pitch(fb, 1, rotation);
3175 return -EINVAL;
3176 }
3177 3153
3178 if (!plane_state->base.visible) 3154 if (!plane_state->base.visible)
3179 return 0; 3155 return 0;
@@ -3189,7 +3165,7 @@ int skl_check_plane_surface(const struct intel_crtc_state *crtc_state,
3189 * the main surface setup depends on it. 3165 * the main surface setup depends on it.
3190 */ 3166 */
3191 if (fb->format->format == DRM_FORMAT_NV12) { 3167 if (fb->format->format == DRM_FORMAT_NV12) {
3192 ret = skl_check_nv12_surface(crtc_state, plane_state); 3168 ret = skl_check_nv12_surface(plane_state);
3193 if (ret) 3169 if (ret)
3194 return ret; 3170 return ret;
3195 ret = skl_check_nv12_aux_surface(plane_state); 3171 ret = skl_check_nv12_aux_surface(plane_state);
@@ -3200,18 +3176,45 @@ int skl_check_plane_surface(const struct intel_crtc_state *crtc_state,
3200 if (ret) 3176 if (ret)
3201 return ret; 3177 return ret;
3202 } else { 3178 } else {
3203 plane_state->aux.offset = ~0xfff; 3179 plane_state->color_plane[1].offset = ~0xfff;
3204 plane_state->aux.x = 0; 3180 plane_state->color_plane[1].x = 0;
3205 plane_state->aux.y = 0; 3181 plane_state->color_plane[1].y = 0;
3206 } 3182 }
3207 3183
3208 ret = skl_check_main_surface(crtc_state, plane_state); 3184 ret = skl_check_main_surface(plane_state);
3209 if (ret) 3185 if (ret)
3210 return ret; 3186 return ret;
3211 3187
3212 return 0; 3188 return 0;
3213} 3189}
3214 3190
3191unsigned int
3192i9xx_plane_max_stride(struct intel_plane *plane,
3193 u32 pixel_format, u64 modifier,
3194 unsigned int rotation)
3195{
3196 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
3197
3198 if (!HAS_GMCH_DISPLAY(dev_priv)) {
3199 return 32*1024;
3200 } else if (INTEL_GEN(dev_priv) >= 4) {
3201 if (modifier == I915_FORMAT_MOD_X_TILED)
3202 return 16*1024;
3203 else
3204 return 32*1024;
3205 } else if (INTEL_GEN(dev_priv) >= 3) {
3206 if (modifier == I915_FORMAT_MOD_X_TILED)
3207 return 8*1024;
3208 else
3209 return 16*1024;
3210 } else {
3211 if (plane->i9xx_plane == PLANE_C)
3212 return 4*1024;
3213 else
3214 return 8*1024;
3215 }
3216}
3217
3215static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state, 3218static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state,
3216 const struct intel_plane_state *plane_state) 3219 const struct intel_plane_state *plane_state)
3217{ 3220{
@@ -3278,21 +3281,25 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
3278{ 3281{
3279 struct drm_i915_private *dev_priv = 3282 struct drm_i915_private *dev_priv =
3280 to_i915(plane_state->base.plane->dev); 3283 to_i915(plane_state->base.plane->dev);
3284 const struct drm_framebuffer *fb = plane_state->base.fb;
3285 unsigned int rotation = plane_state->base.rotation;
3281 int src_x = plane_state->base.src.x1 >> 16; 3286 int src_x = plane_state->base.src.x1 >> 16;
3282 int src_y = plane_state->base.src.y1 >> 16; 3287 int src_y = plane_state->base.src.y1 >> 16;
3283 u32 offset; 3288 u32 offset;
3284 3289
3290 intel_fill_fb_ggtt_view(&plane_state->view, fb, rotation);
3291 plane_state->color_plane[0].stride = intel_fb_pitch(fb, 0, rotation);
3292
3285 intel_add_fb_offsets(&src_x, &src_y, plane_state, 0); 3293 intel_add_fb_offsets(&src_x, &src_y, plane_state, 0);
3286 3294
3287 if (INTEL_GEN(dev_priv) >= 4) 3295 if (INTEL_GEN(dev_priv) >= 4)
3288 offset = intel_compute_tile_offset(&src_x, &src_y, 3296 offset = intel_plane_compute_aligned_offset(&src_x, &src_y,
3289 plane_state, 0); 3297 plane_state, 0);
3290 else 3298 else
3291 offset = 0; 3299 offset = 0;
3292 3300
3293 /* HSW/BDW do this automagically in hardware */ 3301 /* HSW/BDW do this automagically in hardware */
3294 if (!IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv)) { 3302 if (!IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv)) {
3295 unsigned int rotation = plane_state->base.rotation;
3296 int src_w = drm_rect_width(&plane_state->base.src) >> 16; 3303 int src_w = drm_rect_width(&plane_state->base.src) >> 16;
3297 int src_h = drm_rect_height(&plane_state->base.src) >> 16; 3304 int src_h = drm_rect_height(&plane_state->base.src) >> 16;
3298 3305
@@ -3304,9 +3311,43 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
3304 } 3311 }
3305 } 3312 }
3306 3313
3307 plane_state->main.offset = offset; 3314 plane_state->color_plane[0].offset = offset;
3308 plane_state->main.x = src_x; 3315 plane_state->color_plane[0].x = src_x;
3309 plane_state->main.y = src_y; 3316 plane_state->color_plane[0].y = src_y;
3317
3318 return 0;
3319}
3320
3321static int
3322i9xx_plane_check(struct intel_crtc_state *crtc_state,
3323 struct intel_plane_state *plane_state)
3324{
3325 int ret;
3326
3327 ret = chv_plane_check_rotation(plane_state);
3328 if (ret)
3329 return ret;
3330
3331 ret = drm_atomic_helper_check_plane_state(&plane_state->base,
3332 &crtc_state->base,
3333 DRM_PLANE_HELPER_NO_SCALING,
3334 DRM_PLANE_HELPER_NO_SCALING,
3335 false, true);
3336 if (ret)
3337 return ret;
3338
3339 if (!plane_state->base.visible)
3340 return 0;
3341
3342 ret = intel_plane_check_src_coordinates(plane_state);
3343 if (ret)
3344 return ret;
3345
3346 ret = i9xx_check_plane_surface(plane_state);
3347 if (ret)
3348 return ret;
3349
3350 plane_state->ctl = i9xx_plane_ctl(crtc_state, plane_state);
3310 3351
3311 return 0; 3352 return 0;
3312} 3353}
@@ -3316,20 +3357,19 @@ static void i9xx_update_plane(struct intel_plane *plane,
3316 const struct intel_plane_state *plane_state) 3357 const struct intel_plane_state *plane_state)
3317{ 3358{
3318 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 3359 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
3319 const struct drm_framebuffer *fb = plane_state->base.fb;
3320 enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; 3360 enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
3321 u32 linear_offset; 3361 u32 linear_offset;
3322 u32 dspcntr = plane_state->ctl; 3362 u32 dspcntr = plane_state->ctl;
3323 i915_reg_t reg = DSPCNTR(i9xx_plane); 3363 i915_reg_t reg = DSPCNTR(i9xx_plane);
3324 int x = plane_state->main.x; 3364 int x = plane_state->color_plane[0].x;
3325 int y = plane_state->main.y; 3365 int y = plane_state->color_plane[0].y;
3326 unsigned long irqflags; 3366 unsigned long irqflags;
3327 u32 dspaddr_offset; 3367 u32 dspaddr_offset;
3328 3368
3329 linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); 3369 linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
3330 3370
3331 if (INTEL_GEN(dev_priv) >= 4) 3371 if (INTEL_GEN(dev_priv) >= 4)
3332 dspaddr_offset = plane_state->main.offset; 3372 dspaddr_offset = plane_state->color_plane[0].offset;
3333 else 3373 else
3334 dspaddr_offset = linear_offset; 3374 dspaddr_offset = linear_offset;
3335 3375
@@ -3353,7 +3393,7 @@ static void i9xx_update_plane(struct intel_plane *plane,
3353 3393
3354 I915_WRITE_FW(reg, dspcntr); 3394 I915_WRITE_FW(reg, dspcntr);
3355 3395
3356 I915_WRITE_FW(DSPSTRIDE(i9xx_plane), fb->pitches[0]); 3396 I915_WRITE_FW(DSPSTRIDE(i9xx_plane), plane_state->color_plane[0].stride);
3357 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { 3397 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
3358 I915_WRITE_FW(DSPSURF(i9xx_plane), 3398 I915_WRITE_FW(DSPSURF(i9xx_plane),
3359 intel_plane_ggtt_offset(plane_state) + 3399 intel_plane_ggtt_offset(plane_state) +
@@ -3428,12 +3468,12 @@ static bool i9xx_plane_get_hw_state(struct intel_plane *plane,
3428} 3468}
3429 3469
3430static u32 3470static u32
3431intel_fb_stride_alignment(const struct drm_framebuffer *fb, int plane) 3471intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane)
3432{ 3472{
3433 if (fb->modifier == DRM_FORMAT_MOD_LINEAR) 3473 if (fb->modifier == DRM_FORMAT_MOD_LINEAR)
3434 return 64; 3474 return 64;
3435 else 3475 else
3436 return intel_tile_width_bytes(fb, plane); 3476 return intel_tile_width_bytes(fb, color_plane);
3437} 3477}
3438 3478
3439static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id) 3479static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id)
@@ -3463,24 +3503,24 @@ static void skl_detach_scalers(struct intel_crtc *intel_crtc)
3463 } 3503 }
3464} 3504}
3465 3505
3466u32 skl_plane_stride(const struct drm_framebuffer *fb, int plane, 3506u32 skl_plane_stride(const struct intel_plane_state *plane_state,
3467 unsigned int rotation) 3507 int color_plane)
3468{ 3508{
3469 u32 stride; 3509 const struct drm_framebuffer *fb = plane_state->base.fb;
3510 unsigned int rotation = plane_state->base.rotation;
3511 u32 stride = plane_state->color_plane[color_plane].stride;
3470 3512
3471 if (plane >= fb->format->num_planes) 3513 if (color_plane >= fb->format->num_planes)
3472 return 0; 3514 return 0;
3473 3515
3474 stride = intel_fb_pitch(fb, plane, rotation);
3475
3476 /* 3516 /*
3477 * The stride is either expressed as a multiple of 64 bytes chunks for 3517 * The stride is either expressed as a multiple of 64 bytes chunks for
3478 * linear buffers or in number of tiles for tiled buffers. 3518 * linear buffers or in number of tiles for tiled buffers.
3479 */ 3519 */
3480 if (drm_rotation_90_or_270(rotation)) 3520 if (drm_rotation_90_or_270(rotation))
3481 stride /= intel_tile_height(fb, plane); 3521 stride /= intel_tile_height(fb, color_plane);
3482 else 3522 else
3483 stride /= intel_fb_stride_alignment(fb, plane); 3523 stride /= intel_fb_stride_alignment(fb, color_plane);
3484 3524
3485 return stride; 3525 return stride;
3486} 3526}
@@ -6014,6 +6054,8 @@ static void valleyview_crtc_enable(struct intel_crtc_state *pipe_config,
6014 6054
6015 i9xx_set_pipeconf(intel_crtc); 6055 i9xx_set_pipeconf(intel_crtc);
6016 6056
6057 intel_color_set_csc(&pipe_config->base);
6058
6017 intel_crtc->active = true; 6059 intel_crtc->active = true;
6018 6060
6019 intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); 6061 intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
@@ -6113,8 +6155,8 @@ static void i9xx_pfit_disable(struct intel_crtc *crtc)
6113 6155
6114 assert_pipe_disabled(dev_priv, crtc->pipe); 6156 assert_pipe_disabled(dev_priv, crtc->pipe);
6115 6157
6116 DRM_DEBUG_DRIVER("disabling pfit, current: 0x%08x\n", 6158 DRM_DEBUG_KMS("disabling pfit, current: 0x%08x\n",
6117 I915_READ(PFIT_CONTROL)); 6159 I915_READ(PFIT_CONTROL));
6118 I915_WRITE(PFIT_CONTROL, 0); 6160 I915_WRITE(PFIT_CONTROL, 0);
6119} 6161}
6120 6162
@@ -8634,8 +8676,8 @@ static int ironlake_crtc_compute_clock(struct intel_crtc *crtc,
8634 ironlake_compute_dpll(crtc, crtc_state, NULL); 8676 ironlake_compute_dpll(crtc, crtc_state, NULL);
8635 8677
8636 if (!intel_get_shared_dpll(crtc, crtc_state, NULL)) { 8678 if (!intel_get_shared_dpll(crtc, crtc_state, NULL)) {
8637 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", 8679 DRM_DEBUG_KMS("failed to find PLL for pipe %c\n",
8638 pipe_name(crtc->pipe)); 8680 pipe_name(crtc->pipe));
8639 return -EINVAL; 8681 return -EINVAL;
8640 } 8682 }
8641 8683
@@ -9202,8 +9244,8 @@ static int haswell_crtc_compute_clock(struct intel_crtc *crtc,
9202 intel_get_crtc_new_encoder(state, crtc_state); 9244 intel_get_crtc_new_encoder(state, crtc_state);
9203 9245
9204 if (!intel_get_shared_dpll(crtc, crtc_state, encoder)) { 9246 if (!intel_get_shared_dpll(crtc, crtc_state, encoder)) {
9205 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", 9247 DRM_DEBUG_KMS("failed to find PLL for pipe %c\n",
9206 pipe_name(crtc->pipe)); 9248 pipe_name(crtc->pipe));
9207 return -EINVAL; 9249 return -EINVAL;
9208 } 9250 }
9209 } 9251 }
@@ -9592,7 +9634,7 @@ static u32 intel_cursor_base(const struct intel_plane_state *plane_state)
9592 else 9634 else
9593 base = intel_plane_ggtt_offset(plane_state); 9635 base = intel_plane_ggtt_offset(plane_state);
9594 9636
9595 base += plane_state->main.offset; 9637 base += plane_state->color_plane[0].offset;
9596 9638
9597 /* ILK+ do this automagically */ 9639 /* ILK+ do this automagically */
9598 if (HAS_GMCH_DISPLAY(dev_priv) && 9640 if (HAS_GMCH_DISPLAY(dev_priv) &&
@@ -9635,14 +9677,44 @@ static bool intel_cursor_size_ok(const struct intel_plane_state *plane_state)
9635 height > 0 && height <= config->cursor_height; 9677 height > 0 && height <= config->cursor_height;
9636} 9678}
9637 9679
9638static int intel_check_cursor(struct intel_crtc_state *crtc_state, 9680static int intel_cursor_check_surface(struct intel_plane_state *plane_state)
9639 struct intel_plane_state *plane_state)
9640{ 9681{
9641 const struct drm_framebuffer *fb = plane_state->base.fb; 9682 const struct drm_framebuffer *fb = plane_state->base.fb;
9683 unsigned int rotation = plane_state->base.rotation;
9642 int src_x, src_y; 9684 int src_x, src_y;
9643 u32 offset; 9685 u32 offset;
9686
9687 intel_fill_fb_ggtt_view(&plane_state->view, fb, rotation);
9688 plane_state->color_plane[0].stride = intel_fb_pitch(fb, 0, rotation);
9689
9690 src_x = plane_state->base.src_x >> 16;
9691 src_y = plane_state->base.src_y >> 16;
9692
9693 intel_add_fb_offsets(&src_x, &src_y, plane_state, 0);
9694 offset = intel_plane_compute_aligned_offset(&src_x, &src_y,
9695 plane_state, 0);
9696
9697 if (src_x != 0 || src_y != 0) {
9698 DRM_DEBUG_KMS("Arbitrary cursor panning not supported\n");
9699 return -EINVAL;
9700 }
9701
9702 plane_state->color_plane[0].offset = offset;
9703
9704 return 0;
9705}
9706
9707static int intel_check_cursor(struct intel_crtc_state *crtc_state,
9708 struct intel_plane_state *plane_state)
9709{
9710 const struct drm_framebuffer *fb = plane_state->base.fb;
9644 int ret; 9711 int ret;
9645 9712
9713 if (fb && fb->modifier != DRM_FORMAT_MOD_LINEAR) {
9714 DRM_DEBUG_KMS("cursor cannot be tiled\n");
9715 return -EINVAL;
9716 }
9717
9646 ret = drm_atomic_helper_check_plane_state(&plane_state->base, 9718 ret = drm_atomic_helper_check_plane_state(&plane_state->base,
9647 &crtc_state->base, 9719 &crtc_state->base,
9648 DRM_PLANE_HELPER_NO_SCALING, 9720 DRM_PLANE_HELPER_NO_SCALING,
@@ -9651,39 +9723,35 @@ static int intel_check_cursor(struct intel_crtc_state *crtc_state,
9651 if (ret) 9723 if (ret)
9652 return ret; 9724 return ret;
9653 9725
9654 if (!fb) 9726 if (!plane_state->base.visible)
9655 return 0; 9727 return 0;
9656 9728
9657 if (fb->modifier != DRM_FORMAT_MOD_LINEAR) { 9729 ret = intel_plane_check_src_coordinates(plane_state);
9658 DRM_DEBUG_KMS("cursor cannot be tiled\n"); 9730 if (ret)
9659 return -EINVAL; 9731 return ret;
9660 }
9661
9662 src_x = plane_state->base.src_x >> 16;
9663 src_y = plane_state->base.src_y >> 16;
9664
9665 intel_add_fb_offsets(&src_x, &src_y, plane_state, 0);
9666 offset = intel_compute_tile_offset(&src_x, &src_y, plane_state, 0);
9667
9668 if (src_x != 0 || src_y != 0) {
9669 DRM_DEBUG_KMS("Arbitrary cursor panning not supported\n");
9670 return -EINVAL;
9671 }
9672 9732
9673 plane_state->main.offset = offset; 9733 ret = intel_cursor_check_surface(plane_state);
9734 if (ret)
9735 return ret;
9674 9736
9675 return 0; 9737 return 0;
9676} 9738}
9677 9739
9740static unsigned int
9741i845_cursor_max_stride(struct intel_plane *plane,
9742 u32 pixel_format, u64 modifier,
9743 unsigned int rotation)
9744{
9745 return 2048;
9746}
9747
9678static u32 i845_cursor_ctl(const struct intel_crtc_state *crtc_state, 9748static u32 i845_cursor_ctl(const struct intel_crtc_state *crtc_state,
9679 const struct intel_plane_state *plane_state) 9749 const struct intel_plane_state *plane_state)
9680{ 9750{
9681 const struct drm_framebuffer *fb = plane_state->base.fb;
9682
9683 return CURSOR_ENABLE | 9751 return CURSOR_ENABLE |
9684 CURSOR_GAMMA_ENABLE | 9752 CURSOR_GAMMA_ENABLE |
9685 CURSOR_FORMAT_ARGB | 9753 CURSOR_FORMAT_ARGB |
9686 CURSOR_STRIDE(fb->pitches[0]); 9754 CURSOR_STRIDE(plane_state->color_plane[0].stride);
9687} 9755}
9688 9756
9689static bool i845_cursor_size_ok(const struct intel_plane_state *plane_state) 9757static bool i845_cursor_size_ok(const struct intel_plane_state *plane_state)
@@ -9719,6 +9787,9 @@ static int i845_check_cursor(struct intel_crtc_state *crtc_state,
9719 return -EINVAL; 9787 return -EINVAL;
9720 } 9788 }
9721 9789
9790 WARN_ON(plane_state->base.visible &&
9791 plane_state->color_plane[0].stride != fb->pitches[0]);
9792
9722 switch (fb->pitches[0]) { 9793 switch (fb->pitches[0]) {
9723 case 256: 9794 case 256:
9724 case 512: 9795 case 512:
@@ -9807,6 +9878,14 @@ static bool i845_cursor_get_hw_state(struct intel_plane *plane,
9807 return ret; 9878 return ret;
9808} 9879}
9809 9880
9881static unsigned int
9882i9xx_cursor_max_stride(struct intel_plane *plane,
9883 u32 pixel_format, u64 modifier,
9884 unsigned int rotation)
9885{
9886 return plane->base.dev->mode_config.cursor_width * 4;
9887}
9888
9810static u32 i9xx_cursor_ctl(const struct intel_crtc_state *crtc_state, 9889static u32 i9xx_cursor_ctl(const struct intel_crtc_state *crtc_state,
9811 const struct intel_plane_state *plane_state) 9890 const struct intel_plane_state *plane_state)
9812{ 9891{
@@ -9912,6 +9991,9 @@ static int i9xx_check_cursor(struct intel_crtc_state *crtc_state,
9912 return -EINVAL; 9991 return -EINVAL;
9913 } 9992 }
9914 9993
9994 WARN_ON(plane_state->base.visible &&
9995 plane_state->color_plane[0].stride != fb->pitches[0]);
9996
9915 if (fb->pitches[0] != plane_state->base.crtc_w * fb->format->cpp[0]) { 9997 if (fb->pitches[0] != plane_state->base.crtc_w * fb->format->cpp[0]) {
9916 DRM_DEBUG_KMS("Invalid cursor stride (%u) (cursor width %d)\n", 9998 DRM_DEBUG_KMS("Invalid cursor stride (%u) (cursor width %d)\n",
9917 fb->pitches[0], plane_state->base.crtc_w); 9999 fb->pitches[0], plane_state->base.crtc_w);
@@ -12982,7 +13064,7 @@ static int intel_plane_pin_fb(struct intel_plane_state *plane_state)
12982 } 13064 }
12983 13065
12984 vma = intel_pin_and_fence_fb_obj(fb, 13066 vma = intel_pin_and_fence_fb_obj(fb,
12985 plane_state->base.rotation, 13067 &plane_state->view,
12986 intel_plane_uses_fence(plane_state), 13068 intel_plane_uses_fence(plane_state),
12987 &plane_state->flags); 13069 &plane_state->flags);
12988 if (IS_ERR(vma)) 13070 if (IS_ERR(vma))
@@ -13160,19 +13242,17 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
13160} 13242}
13161 13243
13162int 13244int
13163skl_max_scale(struct intel_crtc *intel_crtc, 13245skl_max_scale(const struct intel_crtc_state *crtc_state,
13164 struct intel_crtc_state *crtc_state, 13246 u32 pixel_format)
13165 uint32_t pixel_format)
13166{ 13247{
13167 struct drm_i915_private *dev_priv; 13248 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
13249 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
13168 int max_scale, mult; 13250 int max_scale, mult;
13169 int crtc_clock, max_dotclk, tmpclk1, tmpclk2; 13251 int crtc_clock, max_dotclk, tmpclk1, tmpclk2;
13170 13252
13171 if (!intel_crtc || !crtc_state->base.enable) 13253 if (!crtc_state->base.enable)
13172 return DRM_PLANE_HELPER_NO_SCALING; 13254 return DRM_PLANE_HELPER_NO_SCALING;
13173 13255
13174 dev_priv = to_i915(intel_crtc->base.dev);
13175
13176 crtc_clock = crtc_state->base.adjusted_mode.crtc_clock; 13256 crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
13177 max_dotclk = to_intel_atomic_state(crtc_state->base.state)->cdclk.logical.cdclk; 13257 max_dotclk = to_intel_atomic_state(crtc_state->base.state)->cdclk.logical.cdclk;
13178 13258
@@ -13196,61 +13276,6 @@ skl_max_scale(struct intel_crtc *intel_crtc,
13196 return max_scale; 13276 return max_scale;
13197} 13277}
13198 13278
13199static int
13200intel_check_primary_plane(struct intel_crtc_state *crtc_state,
13201 struct intel_plane_state *state)
13202{
13203 struct intel_plane *plane = to_intel_plane(state->base.plane);
13204 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
13205 struct drm_crtc *crtc = state->base.crtc;
13206 int min_scale = DRM_PLANE_HELPER_NO_SCALING;
13207 int max_scale = DRM_PLANE_HELPER_NO_SCALING;
13208 bool can_position = false;
13209 int ret;
13210 uint32_t pixel_format = 0;
13211
13212 if (INTEL_GEN(dev_priv) >= 9) {
13213 /* use scaler when colorkey is not required */
13214 if (!state->ckey.flags) {
13215 min_scale = 1;
13216 if (state->base.fb)
13217 pixel_format = state->base.fb->format->format;
13218 max_scale = skl_max_scale(to_intel_crtc(crtc),
13219 crtc_state, pixel_format);
13220 }
13221 can_position = true;
13222 }
13223
13224 ret = drm_atomic_helper_check_plane_state(&state->base,
13225 &crtc_state->base,
13226 min_scale, max_scale,
13227 can_position, true);
13228 if (ret)
13229 return ret;
13230
13231 if (!state->base.fb)
13232 return 0;
13233
13234 if (INTEL_GEN(dev_priv) >= 9) {
13235 ret = skl_check_plane_surface(crtc_state, state);
13236 if (ret)
13237 return ret;
13238
13239 state->ctl = skl_plane_ctl(crtc_state, state);
13240 } else {
13241 ret = i9xx_check_plane_surface(state);
13242 if (ret)
13243 return ret;
13244
13245 state->ctl = i9xx_plane_ctl(crtc_state, state);
13246 }
13247
13248 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
13249 state->color_ctl = glk_plane_color_ctl(crtc_state, state);
13250
13251 return 0;
13252}
13253
13254static void intel_begin_crtc_commit(struct drm_crtc *crtc, 13279static void intel_begin_crtc_commit(struct drm_crtc *crtc,
13255 struct drm_crtc_state *old_crtc_state) 13280 struct drm_crtc_state *old_crtc_state)
13256{ 13281{
@@ -13672,12 +13697,8 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
13672 13697
13673 primary->base.state = &state->base; 13698 primary->base.state = &state->base;
13674 13699
13675 primary->can_scale = false; 13700 if (INTEL_GEN(dev_priv) >= 9)
13676 primary->max_downscale = 1;
13677 if (INTEL_GEN(dev_priv) >= 9) {
13678 primary->can_scale = true;
13679 state->scaler_id = -1; 13701 state->scaler_id = -1;
13680 }
13681 primary->pipe = pipe; 13702 primary->pipe = pipe;
13682 /* 13703 /*
13683 * On gen2/3 only plane A can do FBC, but the panel fitter and LVDS 13704 * On gen2/3 only plane A can do FBC, but the panel fitter and LVDS
@@ -13704,8 +13725,6 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
13704 fbc->possible_framebuffer_bits |= primary->frontbuffer_bit; 13725 fbc->possible_framebuffer_bits |= primary->frontbuffer_bit;
13705 } 13726 }
13706 13727
13707 primary->check_plane = intel_check_primary_plane;
13708
13709 if (INTEL_GEN(dev_priv) >= 9) { 13728 if (INTEL_GEN(dev_priv) >= 9) {
13710 primary->has_ccs = skl_plane_has_ccs(dev_priv, pipe, 13729 primary->has_ccs = skl_plane_has_ccs(dev_priv, pipe,
13711 PLANE_PRIMARY); 13730 PLANE_PRIMARY);
@@ -13723,9 +13742,11 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
13723 else 13742 else
13724 modifiers = skl_format_modifiers_noccs; 13743 modifiers = skl_format_modifiers_noccs;
13725 13744
13745 primary->max_stride = skl_plane_max_stride;
13726 primary->update_plane = skl_update_plane; 13746 primary->update_plane = skl_update_plane;
13727 primary->disable_plane = skl_disable_plane; 13747 primary->disable_plane = skl_disable_plane;
13728 primary->get_hw_state = skl_plane_get_hw_state; 13748 primary->get_hw_state = skl_plane_get_hw_state;
13749 primary->check_plane = skl_plane_check;
13729 13750
13730 plane_funcs = &skl_plane_funcs; 13751 plane_funcs = &skl_plane_funcs;
13731 } else if (INTEL_GEN(dev_priv) >= 4) { 13752 } else if (INTEL_GEN(dev_priv) >= 4) {
@@ -13733,9 +13754,11 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
13733 num_formats = ARRAY_SIZE(i965_primary_formats); 13754 num_formats = ARRAY_SIZE(i965_primary_formats);
13734 modifiers = i9xx_format_modifiers; 13755 modifiers = i9xx_format_modifiers;
13735 13756
13757 primary->max_stride = i9xx_plane_max_stride;
13736 primary->update_plane = i9xx_update_plane; 13758 primary->update_plane = i9xx_update_plane;
13737 primary->disable_plane = i9xx_disable_plane; 13759 primary->disable_plane = i9xx_disable_plane;
13738 primary->get_hw_state = i9xx_plane_get_hw_state; 13760 primary->get_hw_state = i9xx_plane_get_hw_state;
13761 primary->check_plane = i9xx_plane_check;
13739 13762
13740 plane_funcs = &i965_plane_funcs; 13763 plane_funcs = &i965_plane_funcs;
13741 } else { 13764 } else {
@@ -13743,9 +13766,11 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
13743 num_formats = ARRAY_SIZE(i8xx_primary_formats); 13766 num_formats = ARRAY_SIZE(i8xx_primary_formats);
13744 modifiers = i9xx_format_modifiers; 13767 modifiers = i9xx_format_modifiers;
13745 13768
13769 primary->max_stride = i9xx_plane_max_stride;
13746 primary->update_plane = i9xx_update_plane; 13770 primary->update_plane = i9xx_update_plane;
13747 primary->disable_plane = i9xx_disable_plane; 13771 primary->disable_plane = i9xx_disable_plane;
13748 primary->get_hw_state = i9xx_plane_get_hw_state; 13772 primary->get_hw_state = i9xx_plane_get_hw_state;
13773 primary->check_plane = i9xx_plane_check;
13749 13774
13750 plane_funcs = &i8xx_plane_funcs; 13775 plane_funcs = &i8xx_plane_funcs;
13751 } 13776 }
@@ -13842,19 +13867,19 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv,
13842 13867
13843 cursor->base.state = &state->base; 13868 cursor->base.state = &state->base;
13844 13869
13845 cursor->can_scale = false;
13846 cursor->max_downscale = 1;
13847 cursor->pipe = pipe; 13870 cursor->pipe = pipe;
13848 cursor->i9xx_plane = (enum i9xx_plane_id) pipe; 13871 cursor->i9xx_plane = (enum i9xx_plane_id) pipe;
13849 cursor->id = PLANE_CURSOR; 13872 cursor->id = PLANE_CURSOR;
13850 cursor->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, cursor->id); 13873 cursor->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, cursor->id);
13851 13874
13852 if (IS_I845G(dev_priv) || IS_I865G(dev_priv)) { 13875 if (IS_I845G(dev_priv) || IS_I865G(dev_priv)) {
13876 cursor->max_stride = i845_cursor_max_stride;
13853 cursor->update_plane = i845_update_cursor; 13877 cursor->update_plane = i845_update_cursor;
13854 cursor->disable_plane = i845_disable_cursor; 13878 cursor->disable_plane = i845_disable_cursor;
13855 cursor->get_hw_state = i845_cursor_get_hw_state; 13879 cursor->get_hw_state = i845_cursor_get_hw_state;
13856 cursor->check_plane = i845_check_cursor; 13880 cursor->check_plane = i845_check_cursor;
13857 } else { 13881 } else {
13882 cursor->max_stride = i9xx_cursor_max_stride;
13858 cursor->update_plane = i9xx_update_cursor; 13883 cursor->update_plane = i9xx_update_cursor;
13859 cursor->disable_plane = i9xx_disable_cursor; 13884 cursor->disable_plane = i9xx_disable_cursor;
13860 cursor->get_hw_state = i9xx_cursor_get_hw_state; 13885 cursor->get_hw_state = i9xx_cursor_get_hw_state;
@@ -14380,31 +14405,18 @@ static
14380u32 intel_fb_pitch_limit(struct drm_i915_private *dev_priv, 14405u32 intel_fb_pitch_limit(struct drm_i915_private *dev_priv,
14381 uint64_t fb_modifier, uint32_t pixel_format) 14406 uint64_t fb_modifier, uint32_t pixel_format)
14382{ 14407{
14383 u32 gen = INTEL_GEN(dev_priv); 14408 struct intel_crtc *crtc;
14409 struct intel_plane *plane;
14384 14410
14385 if (gen >= 9) { 14411 /*
14386 int cpp = drm_format_plane_cpp(pixel_format, 0); 14412 * We assume the primary plane for pipe A has
14413 * the highest stride limits of them all.
14414 */
14415 crtc = intel_get_crtc_for_pipe(dev_priv, PIPE_A);
14416 plane = to_intel_plane(crtc->base.primary);
14387 14417
14388 /* "The stride in bytes must not exceed the of the size of 8K 14418 return plane->max_stride(plane, pixel_format, fb_modifier,
14389 * pixels and 32K bytes." 14419 DRM_MODE_ROTATE_0);
14390 */
14391 return min(8192 * cpp, 32768);
14392 } else if (gen >= 5 && !HAS_GMCH_DISPLAY(dev_priv)) {
14393 return 32*1024;
14394 } else if (gen >= 4) {
14395 if (fb_modifier == I915_FORMAT_MOD_X_TILED)
14396 return 16*1024;
14397 else
14398 return 32*1024;
14399 } else if (gen >= 3) {
14400 if (fb_modifier == I915_FORMAT_MOD_X_TILED)
14401 return 8*1024;
14402 else
14403 return 16*1024;
14404 } else {
14405 /* XXX DSPC is limited to 4k tiled */
14406 return 8*1024;
14407 }
14408} 14420}
14409 14421
14410static int intel_framebuffer_init(struct intel_framebuffer *intel_fb, 14422static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,