Subversion Repositories Kolibri OS

Rev

Rev 5354 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5354 Rev 6084
Line 63... Line 63...
63
#include 
63
#include 
Line 64... Line 64...
64
 
64
 
65
#include "intel_drv.h"
65
#include "intel_drv.h"
Line 66... Line -...
66
#include "i915_drv.h"
-
 
67
 
-
 
68
static void intel_increase_pllclock(struct drm_device *dev,
-
 
69
				    enum pipe pipe)
-
 
70
{
-
 
71
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
72
	int dpll_reg = DPLL(pipe);
-
 
73
	int dpll;
-
 
74
 
-
 
75
	if (!HAS_GMCH_DISPLAY(dev))
-
 
76
		return;
-
 
77
 
-
 
78
	if (!dev_priv->lvds_downclock_avail)
-
 
79
		return;
-
 
80
 
-
 
81
	dpll = I915_READ(dpll_reg);
-
 
82
	if (!HAS_PIPE_CXSR(dev) && (dpll & DISPLAY_RATE_SELECT_FPA1)) {
-
 
83
		DRM_DEBUG_DRIVER("upclocking LVDS\n");
-
 
84
 
-
 
85
		assert_panel_unlocked(dev_priv, pipe);
-
 
86
 
-
 
87
		dpll &= ~DISPLAY_RATE_SELECT_FPA1;
-
 
88
		I915_WRITE(dpll_reg, dpll);
-
 
89
		intel_wait_for_vblank(dev, pipe);
-
 
90
 
-
 
91
		dpll = I915_READ(dpll_reg);
-
 
92
		if (dpll & DISPLAY_RATE_SELECT_FPA1)
-
 
93
			DRM_DEBUG_DRIVER("failed to upclock LVDS!\n");
-
 
94
	}
-
 
95
}
-
 
96
 
-
 
97
/**
-
 
98
 * intel_mark_fb_busy - mark given planes as busy
-
 
99
 * @dev: DRM device
-
 
100
 * @frontbuffer_bits: bits for the affected planes
-
 
101
 * @ring: optional ring for asynchronous commands
-
 
102
 *
-
 
103
 * This function gets called every time the screen contents change. It can be
-
 
104
 * used to keep e.g. the update rate at the nominal refresh rate with DRRS.
-
 
105
 */
-
 
106
static void intel_mark_fb_busy(struct drm_device *dev,
-
 
107
			       unsigned frontbuffer_bits,
-
 
108
			       struct intel_engine_cs *ring)
-
 
109
{
-
 
110
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
111
	enum pipe pipe;
-
 
112
 
-
 
113
	if (!i915.powersave)
-
 
114
		return;
-
 
115
 
-
 
116
	for_each_pipe(dev_priv, pipe) {
-
 
117
		if (!(frontbuffer_bits & INTEL_FRONTBUFFER_ALL_MASK(pipe)))
-
 
118
			continue;
-
 
119
 
-
 
120
		intel_increase_pllclock(dev, pipe);
-
 
121
		if (ring && intel_fbc_enabled(dev))
-
 
122
			ring->fbc_dirty = true;
-
 
123
	}
-
 
124
}
66
#include "i915_drv.h"
125
 
67
 
126
/**
68
/**
127
 * intel_fb_obj_invalidate - invalidate frontbuffer object
69
 * intel_fb_obj_invalidate - invalidate frontbuffer object
128
 * @obj: GEM object to invalidate
70
 * @obj: GEM object to invalidate
129
 * @ring: set for asynchronous rendering
71
 * @origin: which operation caused the invalidation
130
 *
72
 *
131
 * This function gets called every time rendering on the given object starts and
73
 * This function gets called every time rendering on the given object starts and
132
 * frontbuffer caching (fbc, low refresh rate for DRRS, panel self refresh) must
74
 * frontbuffer caching (fbc, low refresh rate for DRRS, panel self refresh) must
133
 * be invalidated. If @ring is non-NULL any subsequent invalidation will be delayed
75
 * be invalidated. For ORIGIN_CS any subsequent invalidation will be delayed
134
 * until the rendering completes or a flip on this frontbuffer plane is
76
 * until the rendering completes or a flip on this frontbuffer plane is
135
 * scheduled.
77
 * scheduled.
136
 */
78
 */
137
void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj,
79
void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj,
138
			     struct intel_engine_cs *ring)
80
			     enum fb_op_origin origin)
139
{
81
{
Line 140... Line 82...
140
	struct drm_device *dev = obj->base.dev;
82
	struct drm_device *dev = obj->base.dev;
Line 141... Line 83...
141
	struct drm_i915_private *dev_priv = dev->dev_private;
83
	struct drm_i915_private *dev_priv = to_i915(dev);
142
 
84
 
Line 143... Line 85...
143
	WARN_ON(!mutex_is_locked(&dev->struct_mutex));
85
	WARN_ON(!mutex_is_locked(&dev->struct_mutex));
144
 
86
 
145
	if (!obj->frontbuffer_bits)
87
	if (!obj->frontbuffer_bits)
146
		return;
88
		return;
147
 
89
 
148
	if (ring) {
90
	if (origin == ORIGIN_CS) {
149
		mutex_lock(&dev_priv->fb_tracking.lock);
91
		mutex_lock(&dev_priv->fb_tracking.lock);
150
		dev_priv->fb_tracking.busy_bits
92
		dev_priv->fb_tracking.busy_bits
Line 151... Line -...
151
			|= obj->frontbuffer_bits;
-
 
152
		dev_priv->fb_tracking.flip_bits
-
 
153
			&= ~obj->frontbuffer_bits;
93
			|= obj->frontbuffer_bits;
-
 
94
		dev_priv->fb_tracking.flip_bits
-
 
95
			&= ~obj->frontbuffer_bits;
154
		mutex_unlock(&dev_priv->fb_tracking.lock);
96
		mutex_unlock(&dev_priv->fb_tracking.lock);
Line 155... Line 97...
155
	}
97
	}
156
 
98
 
157
	intel_mark_fb_busy(dev, obj->frontbuffer_bits, ring);
99
	intel_psr_invalidate(dev, obj->frontbuffer_bits);
158
 
100
	intel_edp_drrs_invalidate(dev, obj->frontbuffer_bits);
-
 
101
	intel_fbc_invalidate(dev_priv, obj->frontbuffer_bits, origin);
159
	intel_psr_invalidate(dev, obj->frontbuffer_bits);
102
}
160
}
103
 
161
 
104
/**
162
/**
105
 * intel_frontbuffer_flush - flush frontbuffer
163
 * intel_frontbuffer_flush - flush frontbuffer
106
 * @dev: DRM device
164
 * @dev: DRM device
107
 * @frontbuffer_bits: frontbuffer plane tracking bits
165
 * @frontbuffer_bits: frontbuffer plane tracking bits
108
 * @origin: which operation caused the flush
166
 *
109
 *
167
 * This function gets called every time rendering on the given planes has
110
 * This function gets called every time rendering on the given planes has
-
 
111
 * completed and frontbuffer caching can be started again. Flushes will get
168
 * completed and frontbuffer caching can be started again. Flushes will get
112
 * delayed if they're blocked by some outstanding asynchronous rendering.
169
 * delayed if they're blocked by some outstanding asynchronous rendering.
113
 *
Line 170... Line 114...
170
 *
114
 * Can be called without any locks held.
171
 * Can be called without any locks held.
115
 */
172
 */
116
static void intel_frontbuffer_flush(struct drm_device *dev,
173
void intel_frontbuffer_flush(struct drm_device *dev,
117
				    unsigned frontbuffer_bits,
Line 174... Line 118...
174
			     unsigned frontbuffer_bits)
118
				    enum fb_op_origin origin)
175
{
-
 
176
	struct drm_i915_private *dev_priv = dev->dev_private;
119
{
Line 177... Line -...
177
 
-
 
178
	/* Delay flushing when rings are still busy.*/
-
 
179
	mutex_lock(&dev_priv->fb_tracking.lock);
-
 
180
	frontbuffer_bits &= ~dev_priv->fb_tracking.busy_bits;
-
 
181
	mutex_unlock(&dev_priv->fb_tracking.lock);
-
 
182
 
120
	struct drm_i915_private *dev_priv = to_i915(dev);
183
	intel_mark_fb_busy(dev, frontbuffer_bits, NULL);
121
 
184
 
122
	/* Delay flushing when rings are still busy.*/
185
	intel_psr_flush(dev, frontbuffer_bits);
-
 
186
 
123
	mutex_lock(&dev_priv->fb_tracking.lock);
Line 187... Line 124...
187
	/*
124
	frontbuffer_bits &= ~dev_priv->fb_tracking.busy_bits;
188
	 * FIXME: Unconditional fbc flushing here is a rather gross hack and
125
	mutex_unlock(&dev_priv->fb_tracking.lock);
189
	 * needs to be reworked into a proper frontbuffer tracking scheme like
126
 
190
	 * psr employs.
127
	if (!frontbuffer_bits)
-
 
128
		return;
191
	 */
129
 
192
	if (dev_priv->fbc.need_sw_cache_clean) {
130
	intel_edp_drrs_flush(dev, frontbuffer_bits);
193
		dev_priv->fbc.need_sw_cache_clean = false;
131
	intel_psr_flush(dev, frontbuffer_bits, origin);
194
		bdw_fbc_sw_flush(dev, FBC_REND_CACHE_CLEAN);
132
	intel_fbc_flush(dev_priv, frontbuffer_bits, origin);
195
	}
133
}
196
}
134
 
197
 
135
/**
198
/**
136
 * intel_fb_obj_flush - flush frontbuffer object
199
 * intel_fb_obj_flush - flush frontbuffer object
137
 * @obj: GEM object to flush
200
 * @obj: GEM object to flush
138
 * @retire: set when retiring asynchronous rendering
201
 * @retire: set when retiring asynchronous rendering
139
 * @origin: which operation caused the flush
Line 202... Line 140...
202
 *
140
 *
Line 203... Line 141...
203
 * This function gets called every time rendering on the given object has
141
 * This function gets called every time rendering on the given object has
Line 225... Line 163...
225
 
163
 
226
		dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits;
164
		dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits;
227
		mutex_unlock(&dev_priv->fb_tracking.lock);
165
		mutex_unlock(&dev_priv->fb_tracking.lock);
Line 228... Line 166...
228
	}
166
	}
229
 
167
 
Line 230... Line 168...
230
	intel_frontbuffer_flush(dev, frontbuffer_bits);
168
	intel_frontbuffer_flush(dev, frontbuffer_bits, origin);
231
}
169
}
232
 
170
 
Line 243... Line 181...
243
 * Can be called without any locks held.
181
 * Can be called without any locks held.
244
 */
182
 */
245
void intel_frontbuffer_flip_prepare(struct drm_device *dev,
183
void intel_frontbuffer_flip_prepare(struct drm_device *dev,
246
				    unsigned frontbuffer_bits)
184
				    unsigned frontbuffer_bits)
247
{
185
{
248
	struct drm_i915_private *dev_priv = dev->dev_private;
186
	struct drm_i915_private *dev_priv = to_i915(dev);
Line 249... Line 187...
249
 
187
 
250
	mutex_lock(&dev_priv->fb_tracking.lock);
188
	mutex_lock(&dev_priv->fb_tracking.lock);
251
	dev_priv->fb_tracking.flip_bits |= frontbuffer_bits;
189
	dev_priv->fb_tracking.flip_bits |= frontbuffer_bits;
252
	/* Remove stale busy bits due to the old buffer. */
190
	/* Remove stale busy bits due to the old buffer. */
253
	dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits;
191
	dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits;
-
 
192
	mutex_unlock(&dev_priv->fb_tracking.lock);
-
 
193
 
254
	mutex_unlock(&dev_priv->fb_tracking.lock);
194
	intel_psr_single_frame_update(dev, frontbuffer_bits);
Line 255... Line 195...
255
}
195
}
256
 
196
 
257
/**
197
/**
Line 265... Line 205...
265
 * Can be called without any locks held.
205
 * Can be called without any locks held.
266
 */
206
 */
267
void intel_frontbuffer_flip_complete(struct drm_device *dev,
207
void intel_frontbuffer_flip_complete(struct drm_device *dev,
268
				     unsigned frontbuffer_bits)
208
				     unsigned frontbuffer_bits)
269
{
209
{
270
	struct drm_i915_private *dev_priv = dev->dev_private;
210
	struct drm_i915_private *dev_priv = to_i915(dev);
Line 271... Line 211...
271
 
211
 
272
	mutex_lock(&dev_priv->fb_tracking.lock);
212
	mutex_lock(&dev_priv->fb_tracking.lock);
273
	/* Mask any cancelled flips. */
213
	/* Mask any cancelled flips. */
274
	frontbuffer_bits &= dev_priv->fb_tracking.flip_bits;
214
	frontbuffer_bits &= dev_priv->fb_tracking.flip_bits;
275
	dev_priv->fb_tracking.flip_bits &= ~frontbuffer_bits;
215
	dev_priv->fb_tracking.flip_bits &= ~frontbuffer_bits;
Line 276... Line 216...
276
	mutex_unlock(&dev_priv->fb_tracking.lock);
216
	mutex_unlock(&dev_priv->fb_tracking.lock);
-
 
217
 
-
 
218
	intel_frontbuffer_flush(dev, frontbuffer_bits, ORIGIN_FLIP);
-
 
219
}
-
 
220
 
-
 
221
/**
-
 
222
 * intel_frontbuffer_flip - synchronous frontbuffer flip
-
 
223
 * @dev: DRM device
-
 
224
 * @frontbuffer_bits: frontbuffer plane tracking bits
-
 
225
 *
-
 
226
 * This function gets called after scheduling a flip on @obj. This is for
-
 
227
 * synchronous plane updates which will happen on the next vblank and which will
-
 
228
 * not get delayed by pending gpu rendering.
-
 
229
 *
-
 
230
 * Can be called without any locks held.
-
 
231
 */
-
 
232
void intel_frontbuffer_flip(struct drm_device *dev,
-
 
233
			    unsigned frontbuffer_bits)
-
 
234
{
-
 
235
	struct drm_i915_private *dev_priv = to_i915(dev);
-
 
236
 
-
 
237
	mutex_lock(&dev_priv->fb_tracking.lock);
-
 
238
	/* Remove stale busy bits due to the old buffer. */
-
 
239
	dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits;
-
 
240
	mutex_unlock(&dev_priv->fb_tracking.lock);
277
 
241