Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
  1// SPDX-License-Identifier: MIT
  2/*
  3 * Copyright © 2019 Intel Corporation
  4 */
  5
  6#include <drm/drm_atomic_state_helper.h>
  7
  8#include "intel_bw.h"
  9#include "intel_display_types.h"
 10#include "intel_sideband.h"
 11
 12/* Parameters for Qclk Geyserville (QGV) */
 13struct intel_qgv_point {
 14	u16 dclk, t_rp, t_rdpre, t_rc, t_ras, t_rcd;
 15};
 16
 17struct intel_qgv_info {
 18	struct intel_qgv_point points[3];
 19	u8 num_points;
 20	u8 num_channels;
 21	u8 t_bl;
 22	enum intel_dram_type dram_type;
 23};
 24
 25static int icl_pcode_read_mem_global_info(struct drm_i915_private *dev_priv,
 26					  struct intel_qgv_info *qi)
 27{
 28	u32 val = 0;
 29	int ret;
 30
 31	ret = sandybridge_pcode_read(dev_priv,
 32				     ICL_PCODE_MEM_SUBSYSYSTEM_INFO |
 33				     ICL_PCODE_MEM_SS_READ_GLOBAL_INFO,
 34				     &val, NULL);
 35	if (ret)
 36		return ret;
 37
 38	switch (val & 0xf) {
 39	case 0:
 40		qi->dram_type = INTEL_DRAM_DDR4;
 41		break;
 42	case 1:
 43		qi->dram_type = INTEL_DRAM_DDR3;
 44		break;
 45	case 2:
 46		qi->dram_type = INTEL_DRAM_LPDDR3;
 47		break;
 48	case 3:
 49		qi->dram_type = INTEL_DRAM_LPDDR3;
 50		break;
 51	default:
 52		MISSING_CASE(val & 0xf);
 53		break;
 54	}
 55
 56	qi->num_channels = (val & 0xf0) >> 4;
 57	qi->num_points = (val & 0xf00) >> 8;
 58
 59	qi->t_bl = qi->dram_type == INTEL_DRAM_DDR4 ? 4 : 8;
 60
 61	return 0;
 62}
 63
 64static int icl_pcode_read_qgv_point_info(struct drm_i915_private *dev_priv,
 65					 struct intel_qgv_point *sp,
 66					 int point)
 67{
 68	u32 val = 0, val2 = 0;
 69	int ret;
 70
 71	ret = sandybridge_pcode_read(dev_priv,
 72				     ICL_PCODE_MEM_SUBSYSYSTEM_INFO |
 73				     ICL_PCODE_MEM_SS_READ_QGV_POINT_INFO(point),
 74				     &val, &val2);
 75	if (ret)
 76		return ret;
 77
 78	sp->dclk = val & 0xffff;
 79	sp->t_rp = (val & 0xff0000) >> 16;
 80	sp->t_rcd = (val & 0xff000000) >> 24;
 81
 82	sp->t_rdpre = val2 & 0xff;
 83	sp->t_ras = (val2 & 0xff00) >> 8;
 84
 85	sp->t_rc = sp->t_rp + sp->t_ras;
 86
 87	return 0;
 88}
 89
 90static int icl_get_qgv_points(struct drm_i915_private *dev_priv,
 91			      struct intel_qgv_info *qi)
 92{
 93	int i, ret;
 94
 95	ret = icl_pcode_read_mem_global_info(dev_priv, qi);
 96	if (ret)
 97		return ret;
 98
 99	if (WARN_ON(qi->num_points > ARRAY_SIZE(qi->points)))
100		qi->num_points = ARRAY_SIZE(qi->points);
101
102	for (i = 0; i < qi->num_points; i++) {
103		struct intel_qgv_point *sp = &qi->points[i];
104
105		ret = icl_pcode_read_qgv_point_info(dev_priv, sp, i);
106		if (ret)
107			return ret;
108
109		DRM_DEBUG_KMS("QGV %d: DCLK=%d tRP=%d tRDPRE=%d tRAS=%d tRCD=%d tRC=%d\n",
110			      i, sp->dclk, sp->t_rp, sp->t_rdpre, sp->t_ras,
111			      sp->t_rcd, sp->t_rc);
112	}
113
114	return 0;
115}
116
117static int icl_calc_bw(int dclk, int num, int den)
118{
119	/* multiples of 16.666MHz (100/6) */
120	return DIV_ROUND_CLOSEST(num * dclk * 100, den * 6);
121}
122
123static int icl_sagv_max_dclk(const struct intel_qgv_info *qi)
124{
125	u16 dclk = 0;
126	int i;
127
128	for (i = 0; i < qi->num_points; i++)
129		dclk = max(dclk, qi->points[i].dclk);
130
131	return dclk;
132}
133
134struct intel_sa_info {
135	u8 deburst, mpagesize, deprogbwlimit, displayrtids;
136};
137
138static const struct intel_sa_info icl_sa_info = {
139	.deburst = 8,
140	.mpagesize = 16,
141	.deprogbwlimit = 25, /* GB/s */
142	.displayrtids = 128,
143};
144
145static int icl_get_bw_info(struct drm_i915_private *dev_priv)
146{
147	struct intel_qgv_info qi = {};
148	const struct intel_sa_info *sa = &icl_sa_info;
149	bool is_y_tile = true; /* assume y tile may be used */
150	int num_channels;
151	int deinterleave;
152	int ipqdepth, ipqdepthpch;
153	int dclk_max;
154	int maxdebw;
155	int i, ret;
156
157	ret = icl_get_qgv_points(dev_priv, &qi);
158	if (ret) {
159		DRM_DEBUG_KMS("Failed to get memory subsystem information, ignoring bandwidth limits");
160		return ret;
161	}
162	num_channels = qi.num_channels;
163
164	deinterleave = DIV_ROUND_UP(num_channels, is_y_tile ? 4 : 2);
165	dclk_max = icl_sagv_max_dclk(&qi);
166
167	ipqdepthpch = 16;
168
169	maxdebw = min(sa->deprogbwlimit * 1000,
170		      icl_calc_bw(dclk_max, 16, 1) * 6 / 10); /* 60% */
171	ipqdepth = min(ipqdepthpch, sa->displayrtids / num_channels);
172
173	for (i = 0; i < ARRAY_SIZE(dev_priv->max_bw); i++) {
174		struct intel_bw_info *bi = &dev_priv->max_bw[i];
175		int clpchgroup;
176		int j;
177
178		clpchgroup = (sa->deburst * deinterleave / num_channels) << i;
179		bi->num_planes = (ipqdepth - clpchgroup) / clpchgroup + 1;
180
181		bi->num_qgv_points = qi.num_points;
182
183		for (j = 0; j < qi.num_points; j++) {
184			const struct intel_qgv_point *sp = &qi.points[j];
185			int ct, bw;
186
187			/*
188			 * Max row cycle time
189			 *
190			 * FIXME what is the logic behind the
191			 * assumed burst length?
192			 */
193			ct = max_t(int, sp->t_rc, sp->t_rp + sp->t_rcd +
194				   (clpchgroup - 1) * qi.t_bl + sp->t_rdpre);
195			bw = icl_calc_bw(sp->dclk, clpchgroup * 32 * num_channels, ct);
196
197			bi->deratedbw[j] = min(maxdebw,
198					       bw * 9 / 10); /* 90% */
199
200			DRM_DEBUG_KMS("BW%d / QGV %d: num_planes=%d deratedbw=%u\n",
201				      i, j, bi->num_planes, bi->deratedbw[j]);
202		}
203
204		if (bi->num_planes == 1)
205			break;
206	}
207
208	return 0;
209}
210
211static unsigned int icl_max_bw(struct drm_i915_private *dev_priv,
212			       int num_planes, int qgv_point)
213{
214	int i;
215
216	for (i = 0; i < ARRAY_SIZE(dev_priv->max_bw); i++) {
217		const struct intel_bw_info *bi =
218			&dev_priv->max_bw[i];
219
220		/*
221		 * Pcode will not expose all QGV points when
222		 * SAGV is forced to off/min/med/max.
223		 */
224		if (qgv_point >= bi->num_qgv_points)
225			return UINT_MAX;
226
227		if (num_planes >= bi->num_planes)
228			return bi->deratedbw[qgv_point];
229	}
230
231	return 0;
232}
233
234void intel_bw_init_hw(struct drm_i915_private *dev_priv)
235{
236	if (IS_GEN(dev_priv, 11))
237		icl_get_bw_info(dev_priv);
238}
239
240static unsigned int intel_max_data_rate(struct drm_i915_private *dev_priv,
241					int num_planes)
242{
243	if (IS_GEN(dev_priv, 11))
244		/*
245		 * FIXME with SAGV disabled maybe we can assume
246		 * point 1 will always be used? Seems to match
247		 * the behaviour observed in the wild.
248		 */
249		return min3(icl_max_bw(dev_priv, num_planes, 0),
250			    icl_max_bw(dev_priv, num_planes, 1),
251			    icl_max_bw(dev_priv, num_planes, 2));
252	else
253		return UINT_MAX;
254}
255
256static unsigned int intel_bw_crtc_num_active_planes(const struct intel_crtc_state *crtc_state)
257{
258	/*
259	 * We assume cursors are small enough
260	 * to not not cause bandwidth problems.
261	 */
262	return hweight8(crtc_state->active_planes & ~BIT(PLANE_CURSOR));
263}
264
265static unsigned int intel_bw_crtc_data_rate(const struct intel_crtc_state *crtc_state)
266{
267	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
268	unsigned int data_rate = 0;
269	enum plane_id plane_id;
270
271	for_each_plane_id_on_crtc(crtc, plane_id) {
272		/*
273		 * We assume cursors are small enough
274		 * to not not cause bandwidth problems.
275		 */
276		if (plane_id == PLANE_CURSOR)
277			continue;
278
279		data_rate += crtc_state->data_rate[plane_id];
280	}
281
282	return data_rate;
283}
284
285void intel_bw_crtc_update(struct intel_bw_state *bw_state,
286			  const struct intel_crtc_state *crtc_state)
287{
288	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
289
290	bw_state->data_rate[crtc->pipe] =
291		intel_bw_crtc_data_rate(crtc_state);
292	bw_state->num_active_planes[crtc->pipe] =
293		intel_bw_crtc_num_active_planes(crtc_state);
294
295	DRM_DEBUG_KMS("pipe %c data rate %u num active planes %u\n",
296		      pipe_name(crtc->pipe),
297		      bw_state->data_rate[crtc->pipe],
298		      bw_state->num_active_planes[crtc->pipe]);
299}
300
301static unsigned int intel_bw_num_active_planes(struct drm_i915_private *dev_priv,
302					       const struct intel_bw_state *bw_state)
303{
304	unsigned int num_active_planes = 0;
305	enum pipe pipe;
306
307	for_each_pipe(dev_priv, pipe)
308		num_active_planes += bw_state->num_active_planes[pipe];
309
310	return num_active_planes;
311}
312
313static unsigned int intel_bw_data_rate(struct drm_i915_private *dev_priv,
314				       const struct intel_bw_state *bw_state)
315{
316	unsigned int data_rate = 0;
317	enum pipe pipe;
318
319	for_each_pipe(dev_priv, pipe)
320		data_rate += bw_state->data_rate[pipe];
321
322	return data_rate;
323}
324
325static struct intel_bw_state *
326intel_atomic_get_bw_state(struct intel_atomic_state *state)
327{
328	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
329	struct drm_private_state *bw_state;
330
331	bw_state = drm_atomic_get_private_obj_state(&state->base,
332						    &dev_priv->bw_obj);
333	if (IS_ERR(bw_state))
334		return ERR_CAST(bw_state);
335
336	return to_intel_bw_state(bw_state);
337}
338
339int intel_bw_atomic_check(struct intel_atomic_state *state)
340{
341	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
342	struct intel_crtc_state *new_crtc_state, *old_crtc_state;
343	struct intel_bw_state *bw_state = NULL;
344	unsigned int data_rate, max_data_rate;
345	unsigned int num_active_planes;
346	struct intel_crtc *crtc;
347	int i;
348
349	/* FIXME earlier gens need some checks too */
350	if (INTEL_GEN(dev_priv) < 11)
351		return 0;
352
353	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
354					    new_crtc_state, i) {
355		unsigned int old_data_rate =
356			intel_bw_crtc_data_rate(old_crtc_state);
357		unsigned int new_data_rate =
358			intel_bw_crtc_data_rate(new_crtc_state);
359		unsigned int old_active_planes =
360			intel_bw_crtc_num_active_planes(old_crtc_state);
361		unsigned int new_active_planes =
362			intel_bw_crtc_num_active_planes(new_crtc_state);
363
364		/*
365		 * Avoid locking the bw state when
366		 * nothing significant has changed.
367		 */
368		if (old_data_rate == new_data_rate &&
369		    old_active_planes == new_active_planes)
370			continue;
371
372		bw_state  = intel_atomic_get_bw_state(state);
373		if (IS_ERR(bw_state))
374			return PTR_ERR(bw_state);
375
376		bw_state->data_rate[crtc->pipe] = new_data_rate;
377		bw_state->num_active_planes[crtc->pipe] = new_active_planes;
378
379		DRM_DEBUG_KMS("pipe %c data rate %u num active planes %u\n",
380			      pipe_name(crtc->pipe),
381			      bw_state->data_rate[crtc->pipe],
382			      bw_state->num_active_planes[crtc->pipe]);
383	}
384
385	if (!bw_state)
386		return 0;
387
388	data_rate = intel_bw_data_rate(dev_priv, bw_state);
389	num_active_planes = intel_bw_num_active_planes(dev_priv, bw_state);
390
391	max_data_rate = intel_max_data_rate(dev_priv, num_active_planes);
392
393	data_rate = DIV_ROUND_UP(data_rate, 1000);
394
395	if (data_rate > max_data_rate) {
396		DRM_DEBUG_KMS("Bandwidth %u MB/s exceeds max available %d MB/s (%d active planes)\n",
397			      data_rate, max_data_rate, num_active_planes);
398		return -EINVAL;
399	}
400
401	return 0;
402}
403
404static struct drm_private_state *intel_bw_duplicate_state(struct drm_private_obj *obj)
405{
406	struct intel_bw_state *state;
407
408	state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL);
409	if (!state)
410		return NULL;
411
412	__drm_atomic_helper_private_obj_duplicate_state(obj, &state->base);
413
414	return &state->base;
415}
416
417static void intel_bw_destroy_state(struct drm_private_obj *obj,
418				   struct drm_private_state *state)
419{
420	kfree(state);
421}
422
423static const struct drm_private_state_funcs intel_bw_funcs = {
424	.atomic_duplicate_state = intel_bw_duplicate_state,
425	.atomic_destroy_state = intel_bw_destroy_state,
426};
427
428int intel_bw_init(struct drm_i915_private *dev_priv)
429{
430	struct intel_bw_state *state;
431
432	state = kzalloc(sizeof(*state), GFP_KERNEL);
433	if (!state)
434		return -ENOMEM;
435
436	drm_atomic_private_obj_init(&dev_priv->drm, &dev_priv->bw_obj,
437				    &state->base, &intel_bw_funcs);
438
439	return 0;
440}