diff options
author | Dave Airlie <airlied@redhat.com> | 2018-09-27 19:37:51 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2018-09-27 19:37:55 -0400 |
commit | db9825c95498280718c4687fcf712016f5b6f5f6 (patch) | |
tree | 01661a811bcd16a7b6f3ee9790e77da75fd178b0 /drivers/gpu/drm/i915/intel_display.c | |
parent | 156e60bc71aa31a3b42b1d66a822c2999bd0994c (diff) | |
parent | 448626103dad54ec5d06722e955586b5d557625d (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.c | 632 |
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 | ||
1919 | static unsigned int | 1919 | static unsigned int |
1920 | intel_tile_width_bytes(const struct drm_framebuffer *fb, int plane) | 1920 | intel_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 | ||
1967 | static unsigned int | 1967 | static unsigned int |
1968 | intel_tile_height(const struct drm_framebuffer *fb, int plane) | 1968 | intel_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 */ |
1978 | static void intel_tile_dims(const struct drm_framebuffer *fb, int plane, | 1978 | static 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 | ||
1989 | unsigned int | 1989 | unsigned int |
1990 | intel_fb_align_height(const struct drm_framebuffer *fb, | 1990 | intel_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 | ||
2046 | static unsigned int intel_surf_alignment(const struct drm_framebuffer *fb, | 2046 | static 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 | ||
2081 | struct i915_vma * | 2081 | struct i915_vma * |
2082 | intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, | 2082 | intel_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 | ||
2185 | static int intel_fb_pitch(const struct drm_framebuffer *fb, int plane, | 2182 | static 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 | */ |
2200 | u32 intel_fb_xy_to_linear(int x, int y, | 2197 | u32 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 | */ |
2216 | void intel_add_fb_offsets(int *x, int *y, | 2213 | void 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 | ||
2233 | static u32 __intel_adjust_tile_offset(int *x, int *y, | 2230 | static 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 | ||
2260 | static u32 _intel_adjust_tile_offset(int *x, int *y, | 2257 | static 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 | */ |
2302 | static u32 intel_adjust_tile_offset(int *x, int *y, | 2300 | static 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 | */ |
2325 | static u32 _intel_compute_tile_offset(const struct drm_i915_private *dev_priv, | 2325 | static 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 | ||
2376 | u32 intel_compute_tile_offset(int *x, int *y, | 2377 | static 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 */ |
2397 | static int intel_fb_offset_to_xy(int *x, int *y, | 2398 | static 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 | ||
2855 | valid_fb: | 2859 | valid_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 | ||
2902 | static int skl_max_plane_width(const struct drm_framebuffer *fb, int plane, | 2911 | static 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 | ||
2985 | static int skl_check_main_surface(const struct intel_crtc_state *crtc_state, | 2995 | static 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 | ||
3086 | static int | 3072 | static int |
3087 | skl_check_nv12_surface(const struct intel_crtc_state *crtc_state, | 3073 | skl_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 | ||
3165 | int skl_check_plane_surface(const struct intel_crtc_state *crtc_state, | 3144 | int 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 | ||
3191 | unsigned int | ||
3192 | i9xx_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 | |||
3215 | static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state, | 3218 | static 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 | |||
3321 | static int | ||
3322 | i9xx_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 | ||
3430 | static u32 | 3470 | static u32 |
3431 | intel_fb_stride_alignment(const struct drm_framebuffer *fb, int plane) | 3471 | intel_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 | ||
3439 | static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id) | 3479 | static 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 | ||
3466 | u32 skl_plane_stride(const struct drm_framebuffer *fb, int plane, | 3506 | u32 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 | ||
9638 | static int intel_check_cursor(struct intel_crtc_state *crtc_state, | 9680 | static 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 | |||
9707 | static 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 | ||
9740 | static unsigned int | ||
9741 | i845_cursor_max_stride(struct intel_plane *plane, | ||
9742 | u32 pixel_format, u64 modifier, | ||
9743 | unsigned int rotation) | ||
9744 | { | ||
9745 | return 2048; | ||
9746 | } | ||
9747 | |||
9678 | static u32 i845_cursor_ctl(const struct intel_crtc_state *crtc_state, | 9748 | static 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 | ||
9689 | static bool i845_cursor_size_ok(const struct intel_plane_state *plane_state) | 9757 | static 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 | ||
9881 | static unsigned int | ||
9882 | i9xx_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 | |||
9810 | static u32 i9xx_cursor_ctl(const struct intel_crtc_state *crtc_state, | 9889 | static 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 | ||
13162 | int | 13244 | int |
13163 | skl_max_scale(struct intel_crtc *intel_crtc, | 13245 | skl_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 | ||
13199 | static int | ||
13200 | intel_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 | |||
13254 | static void intel_begin_crtc_commit(struct drm_crtc *crtc, | 13279 | static 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 | |||
14380 | u32 intel_fb_pitch_limit(struct drm_i915_private *dev_priv, | 14405 | u32 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 | ||
14410 | static int intel_framebuffer_init(struct intel_framebuffer *intel_fb, | 14422 | static int intel_framebuffer_init(struct intel_framebuffer *intel_fb, |